Mysql query sum and find average [closed] - mysql

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a db table which stores votes made against articles. I would like to query the table to find, within the last 30 days, the articles which on average have received the best overall votes.
I'm looking for some advice on how I should do this, I am guessing I can either do this with PHP or MYSQL. Although I have a better grasp of PHP I would imagine that using MYSQL to get my result is better practice.
CREATE TABLE IF NOT EXISTS `ratings` (
`id` int(11) NOT NULL,
`article_id` int(11) NOT NULL AUTO_INCREMENT,
`rating` int(11) NOT NULL,
`ip` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`timestamp` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2054 ;
Is there a way to sum and find an average given this table structure.
Thnak you.
Alan.

There is a function AVG() in MySQL. So
SELECT AVG(rating)
FROM ratings
WHERE article_id = 1
Will give the average rating of the articles with article_id 1.
There's also a SUM() function in MySQL. So
SELECT SUM(rating)
FROM ratings
WHERE article_id = 1
Will give the sum of all ratings of the articles with article_id 1.

Related

Select Exchange Rate based on Currency and Date [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I've looked around for a solution to this, but at least I was unable to find anything which would at least be similar to my case.
I need to select the exchange rate, based on the date a product was purchased.
Let me try and explain.
I have a table with Currencies:
CREATE TABLE `tblCurrencies` (
`CurrID` int(11) NOT NULL AUTO_INCREMENT,
`CurencySymbol` varchar(1) DEFAULT NULL,
`CurrencyCode` varchar(3) DEFAULT NULL,
`CurrencyDescription` varchar(100) DEFAULT NULL,
PRIMARY KEY (`CurrID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
A table with Exchange Rates:
CREATE TABLE `tblExchRates` (
`ExcID` int(11) NOT NULL AUTO_INCREMENT,
`CurrKey` int(11) DEFAULT NULL,
`Date` date DEFAULT NULL,
`Exchange` decimal(11,3) DEFAULT NULL,
PRIMARY KEY (`ExcID`),
KEY `CurrKey` (`CurrKey`),
CONSTRAINT `tblExchRates_ibfk_1` FOREIGN KEY (`CurrKey`) REFERENCES `tblCurrencies` (`CurrID`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=111 DEFAULT CHARSET=utf8;
And a table with Products (note my products are listed in numbers in the table, which is OK in my case):
CREATE TABLE `tblProducts` (
`ProductID` int(11) NOT NULL AUTO_INCREMENT,
`Contract` int(11) DEFAULT NULL,
`Product` int(11) DEFAULT NULL,
`Type` varchar(100) DEFAULT NULL,
`Currency` int(11) DEFAULT NULL,
`Amount` decimal(10,0) DEFAULT NULL,
`PurchaseDate` datetime DEFAULT NULL,
PRIMARY KEY (`ProductID`),
KEY `Contract` (`Contract`),
KEY `Currency` (`Currency`),
CONSTRAINT `tblShopCart_ibfk_2` FOREIGN KEY (`Currency`) REFERENCES `tblCurrencies` (`CurrID`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `tblShopCart_ibfk_1` FOREIGN KEY (`Contract`) REFERENCES `tblContracts` (`ContractID`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3155 DEFAULT CHARSET=utf8;
In the Exchange Rates table, as an example, values are set like this:
CurrKey Date Exchange
1 15-01-2017 0.850
1 31-01-2017 0.856
1 02-02-2018 0.918
1 18-02-2018 0.905
2 04-02-2018 1.765
2 14-02-2018 1.755
And so on...
I want to have a query that select a unique exchange rate based on the date a product was purchased and the currency it was purchased.
In other words, as an example, if I have a product that was purchased on 07-02-2018, the query has to select the exchange rate which is valid in the relevant date rage that matches the purchase date and its currency. In this example, the correct exchange rage for a product purchased on 07-02-2018 which has a currkey of 1 would be 0.918
Please note that exchange rates are set on random dates (as per example above).
I managed to make this query, but it is not precise, as it sometimes returns two or more results (due to the 10 days range I set), whereas I only need 1 result:
SELECT
tblExchRates.Exchange
FROM
tblCurrencies
INNER JOIN tblExchRates ON tblExchRates.CurrKey = tblCurrencies.CurrID
WHERE
tblCurrencies.CurrencyCode = "EUR" AND
tblExchRates.Date BETWEEN (tblProducts.PurchaseDate - INTERVAL 10 DAY) AND (tblProducts.PurchaseDate + INTERVAL 10 DAY)
For a fairly simple solution you can do
SELECT
p.*
,(SELECT TOP 1 er.Exchange
FROM tblExchRates AS er
INNER JOIN tblCurrencies AS c ON er.CurrKey = c.CurrID AND c.CurrencyCode = 'EUR'
WHERE er.Date <= p.PurchaseDate
ORDER BY er.Date DESC) AS ExchangeRate
FROM
tblProducts AS p
Another option, if you have control over the schema then changing your exchange rates table to have a DateFrom and DateTo rather than just a date would then mean you can simply find the correct exchange rate using the BETWEEN keyword.
I am a beginner myself so no guarantees on correctness. I believe you have to use a certain application programming language along with SQL, for example PHP. Still, I will outline the basic steps I would take.
1. Assign the purchase currency ID and purchase date to variables using a simple SELECT statement. Assume I give the ID to targetID and date to targetDate.
2. SELECT MIN(Date) FROM tblExchRates WHERE Date <= targetDate AND CurrKey =targetID; //Select most recent date whose range includes the date of purchase among the matching currency IDs. Assign the result of this statement to another variable. Assume I used the variable dateRange.
3. SELECT Exchange FROM tblExchRates WHERE Date = targetDate; //Find the exchange rate of the selected date.
Note that there are many ways to do this. For example, you could use table JOINS (refer to this link: https://www.w3schools.com/sql/sql_join.asp ) or select columns from different tables in just one SQL statement (refer to this Stack overflow question: MySQL Select all columns from one table and some from another table). Last, you can use SQL to create variables (refer to this question: Set the variable result, from query) and then perform operations.

MYSQL SELECT statements [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I made a table and I want to select certain data from the table using select statements.
I want to see all the book titles that were published in May.
How can I go about doing this?
Here is the table
CREATE TABLE titles
(
title_id CHAR(3) NOT NULL,
title_name VARCHAR(40) NOT NULL,
type VARCHAR(10) ,
pub_id CHAR(3) NOT NULL,
pages INTEGER ,
price DECIMAL(5,2) ,
sales INTEGER ,
pubdate DATE ,
contract SMALLINT NOT NULL,
CONSTRAINT pk_titles PRIMARY KEY (title_id)
)ENGINE = InnoDB;
I tried this:
SELECT * FROM titles
WHERE pubdate LIKE '%%%%-05-%%';
It displays the whole column, how can I get it to only display the books title?
Try this:
SELECT title_name FROM titles WHERE MONTH(pubdate) = '5'

How can i turn a INT to VARCHAR in SQL [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm working on a database for my database class.
I have been trying to change the INT from SUBJECT_ID to VARCHAR.
This is the code I have been using but it keeps giving me errors:
ALTER TABLE COURSE
ALTER COLUMN SUBJECT_ID VARCHAR(11);
I also tried this:
SELECT CONVERT(VARCHAR(11),SUBJECT_ID) FROM COURSE;
and this is the table I'm working with:
CREATE TABLE COURSE
(COURSE_ID INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
SUBJECT_ID INT(11) NOT NULL,
COURSE_GRADE_LEVEL CHAR(2) NOT NULL,
FAC_ID INT NOT NULL,
FOREIGN KEY(FAC_ID) REFERENCES FACULTY(FAC_ID));
Any suggestions will be appreciated. Thanks.
Try:
ALTER TABLE COURSE MODIFY SUBJECT_ID VARCHAR(11);
select cast(subject_id as varchar(11)) as subject_id_str from course

job seek website database design [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am creating a job seek website with PHP and MySQL, one question is how to design the database better? The basic function of the website is that 'jobseekers' can login and search jobs, upload CVs, and 'employers' can login and post jobs, and browser CVs. Currently I just created 2 tables:
-- Table structure for table users
to analyze the table sturctures for a job seek website(using MySQL and PHP) [on hold]
-- user_type: 0 - jobseekers
-- 1 - employers
-- 2 - administrator
CREATE TABLE users (
user_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
first_name VARCHAR(20) NOT NULL,
last_name VARCHAR(40) NOT NULL,
email VARCHAR(80) NOT NULL,
pass CHAR(40) NOT NULL,
user_type TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
active CHAR(32),
last_login DATETIME NOT NULL,
registration_date DATETIME NOT NULL,
PRIMARY KEY (user_id),
UNIQUE KEY (email),
INDEX login (email, pass)
) ENGINE = INNODB;
-- Table structure for table jobs
CREATE TABLE jobs (
job_id INT(11) NOT NULL AUTO_INCREMENT,
title VARCHAR(200) NOT NULL,
description text NOT NULL,
county VARCHAR(30) NOT NULL,
PRIMARY KEY (job_id)
) ENGINE = MYISAM ;
But I feel just two tables might not be enough, and the user table maybe need to be broke down. Any suggestion how to improve the design?
Perhaps you may want 4 tables;
2 to store the user details
jobseeker_details_table; ( name, address, phonenumber, CV etc)
employer_details_tabel; (name, address, companyname, phone, etc)
than 2 more tables, one for the jobs jobseekers have applied for, and one for the jobs employers have posted - as employers are likely to post more than one job position, and jobseekers and likely to apply for many different jobs, so;
jobs_applied_table; (id, jobid, status, etc)
employer_posted_jobs; (jobid, position_details, date_posted, status, etc)
hope that helps / gives you something to think about.
good luck

mysql select query optimization [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I have two table testa & testb.
CREATE TABLE `testa` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `testb` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT NULL,
`aid1` INT(10) DEFAULT NULL,
`aid2` INT(10) DEFAULT NULL,
`aid3` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`)
);
Currently I am running below query for retrieving all rows where id in testa table matches with any columns of aid1,aid2,aid3 in tableb. The query is retreiving acurate result but it is taking minimum 30 seconds to execute which is too much. I have also tried to optimise my query using UNION but failed to do so.
SELECT a.id, a.name, b.name, b.id
FROM testb b
INNER JOIN testa a ON b.aid1 = a.id OR b.aid2 = a.id OR b.aid3 = a.id ;
How do i optimize my query so it's total execution time is within 2-3 seconds?
Thanks in advance...
Result of EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE b ALL idx_aid1,idx_aid2,idx_aid3 (NULL) (NULL) (NULL) 10940
1 SIMPLE a ALL PRIMARY (NULL) (NULL) (NULL) 7512 Using where; Using join buffer
Because you permit for aid1, aid2, aid3 to be NULL (and apparently, they are mostly NULL per your explanation), your join condition is effectively not indexable.
Why? SQL expression b.aid1 = a.id OR b.aid2 = a.id OR b.aid3 = a.id
evaluates to NULL if any of aid1, aid2 or aid3 is NULL, and this is why MySQL planner does not show using an index.
Solution: do not use NULLs for aid1, aid2, aid3. Instead, invent special id (say 0) which is guaranteed to not exist in testa.
Then, make sure that testb.aid[123] are NOT NULL (and assign it to 0 where it was NULL before).
EDIT: Adding alternative approach to this problem.
You can also solve this problem if you can afford to change your schema by adding one more table. This new table will contain list of aid's you currently store in table testb, and testb will contain just one id linking to new table. This should be similar to what is explained in this answer. Additional advantage to this is that you can permit arbitrary number of aid's (not just 3 as you have now).
In addition to the indexing that others have suggested, make sure you ANALYZE your tables so that the statistics on the tables are up-to-date. If the statistics are wildly different from what's actually in the table, then the query planner will make bad choices.
you should index on the following columns to avoid fulltable scan
`aid1` INT(10) DEFAULT NULL,
`aid2` INT(10) DEFAULT NULL,
`aid3` INT(10) DEFAULT NULL,
if you want to alter the tables
ALTER TABLE testb ADD INDEX (aid1);
ALTER TABLE testb ADD INDEX (aid2);
ALTER TABLE testb ADD INDEX (aid3);
Have You tried joining with IN instead of OR?
SELECT a.id, a.name, b.name, b.id
FROM testb b
INNER JOIN testa a ON a.id IN (b.aid1, b.aid2, b.aid3) ;