I have been using mySQL for a while, but have not really wanted to be this efficient till now. I currently have the following code:
SELECT `page_name` AS manufacturer_name
FROM `manufacturers`
WHERE `id` = '$manufacturers_id'
UNION ALL
SELECT `page_name` AS series_name
FROM `series`
WHERE `id` = '$series_id'
Unfortunately this is not doing what I want, it is selecting the right information for me, but it is putting it all under just one column name: manufacturer_name. How do I modify this to select the page name from manufacturers and series separately? This is the current output I am getting:
manufacturer_name
my_manufacturer_name
my_series_name
This is what I would like to have as output (Note: I just used this as a column separator: |):
manufacturer_name | series_name
my_manufacturer name | my_series_name
If your results contain only single row then use
select
(
SELECT `page_name` AS manufacturer_name
FROM `manufacturers`
WHERE `id` = '$manufacturers_id'
) as manufacturer_name,
(
SELECT `page_name` AS series_name
FROM `series`
WHERE `id` = '$series_id'
) as series_name
Another possibility with UNION is
SELECT `page_name` AS manufacturer_name, null as series_name
FROM `manufacturers`
WHERE `id` = '$manufacturers_id'
UNION ALL
SELECT null, `page_name`
FROM `series`
WHERE `id` = '$series_id'
but this returns 2 rows.
Related
I am trying to develop a rating system with php/mysql.
I have a simple rating object like this:
(t is type of rating, r is value of rating)
[{"t":"1","r":2},{"t":"2","r":4},{"t":"3","r":1},{"t":"4","r":2},{"t":"5","r":2}]
In DB, I have a lot of rating records
Like this:
object1=> [{"t":"1","r":2},{"t":"2","r":4},{"t":"3","r":1},{"t":"4","r":2},{"t":"5","r":2}]
object2=> [{"t":"1","r":1},{"t":"2","r":5},{"t":"3","r":3},{"t":"4","r":3},{"t":"5","r":1}]
In short for output I need a new object like this (I need to calculate average rating, with same keys.)
objectAverageCalculated=> [{"t":"1","r":1.5},{"t":"2","r":4.5},{"t":"3","r":2},{"t":"4","r":2.5},{"t":"5","r":1.5}]
My sql:
CREATE TABLE `ratings` (
`id` int(11) NOT NULL,
`rating` text NOT NULL,
`item_id` varchar(16) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `ratings` (`id`, `rating`, `item_id`) VALUES
(6, '[{\"t\":\"1\",\"r\":2},{\"t\":\"2\",\"r\":4},{\"t\":\"3\",\"r\":1},{\"t\":\"4\",\"r\":2},{\"t\":\"5\",\"r\":2}]', 'ABC123'),
(7, '[{\"t\":\"1\",\"r\":1},{\"t\":\"2\",\"r\":5},{\"t\":\"3\",\"r\":3},{\"t\":\"4\",\"r\":3},{\"t\":\"5\",\"r\":1}]', 'ABC123');
--
ALTER TABLE `ratings`
ADD PRIMARY KEY (`id`);
ALTER TABLE `ratings`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;
COMMIT;
My code
$result = mysqli_query($con, "SELECT * FROM ratings WHERE item_id='ABC123' ");
while ($row = mysqli_fetch_array($result)) {
$tempArray = json_decode($row['rating'], true);
array_push($ratingsRaw, $tempArray);
}
I can not save every object with new variable (like $item1,$item2, etc...)
How can I store every object in one array and how can I get average of every rating type in one output object?
You can use AVG() method in your MySQL query and retrieve average value directly from database.
SELECT AVG(rating) AS avg_rating FROM ratings WHERE item_id='ABC123'
Or when you don't specify ID and you want average value for all items.
SELECT AVG(rating) AS avg_rating, item_id FROM ratings GROUP BY item_id
I've a problem,
I want insert fields in a table if row not exist
My code is:
INSERT INTO `myTable` (
`circuit` ,
`date` ,
`session` ,
`lap` ,
`time`
) SELECT 'misano', '2013-10-11', 1, 1, '0:01:06:332'
FROM `myTable`
WHERE NOT EXISTS (SELECT 1 FROM `myTable` WHERE `circuit` = 'misano' AND `date` = '2013-10-11' AND `session` = 1 AND `lap` = 1 AND `time` = '0:01:06:332')
This code work fine if in "myTable" there is at least one row. If "myTable" is empty, SQL return: 0 row.
If myTable is empty, then a SELECT ... FROM myTable will never produce any rows (even without the WHERE condition).
Use
FROM dual
in the outer select. The DUAL pseudo table always contains exactly one row. The EXISTS sub-query runs against myTable of course.
Edit:
If you have a unique index on myTable, see the solution suggested by Filipe.
If you have a primary key or unique index in your table, you could use INSERT ... ON DUPLICATE KEY UPDATE
INSERT INTO `myTable` (`circuit`, `date`, `session`, `lap`, `time`)
VALUES ('misano', '2013-10-11', 1, 1, '0:01:06:332')
ON DUPLICATE KEY
UPDATE `circuit` = VALUES (`circuit`),
`date` = VALUES (`date`),
`session` = VALUES (`session`),
`lap` = VALUES (`lap`),
`time` = VALUES (`time`)
i have an income and expense table. i want to select them both in a single query and get the difference between the income.amount field and expense.amount field grouping by month. so that the query will return a result whereby the total of expenses amount from the total of income amount basing the calculation on month. i used used two methods but non worked. find the below:
SELECT *, count(*), sum(`transaction`.amount) as tiamount, sum(expenditure.amount) as teamount, monthname(`transaction`.date) as mni, monthname(expenditure.date) as mne
FROM `transaction`, expenditure
WHERE month(expenditure.`date`)=month(`transaction`.`date`) and month(`transaction`.`date`)=month(expenditure.`date`)
GROUP BY monthname(`transaction`.date) ORDER BY `transaction`.date Desc
the other is :
SELECT count(*), `transaction`.date, sum(`transaction`.amount) as tiamount, sum(`transaction`.amount - expenditure.amount) as diff, monthname(`transaction`.date) as mni
FROM `transaction` left join expenditure on monthname(`transaction`.date) = monthname(expenditure.date)
UNION ALL
SELECT count(*), expenditure.date, sum(expenditure.amount) as teamount, sum(`transaction`.amount - expenditure.amount) as diff, monthname(expenditure.date) as mne
FROM expenditure left join `transaction` on monthname(`transaction`.date) = monthname(expenditure.date)
any help would be appreciated. Thanks.
ok thanks all. i solved the issue. each time the page is loaded, it checks to see if the table balance2 already exist, if it does it is dropped and recreated on the fly
mysql_query($query_truncate = "drop table IF EXISTS balance2");
$create= "CREATE TABLE balance2 (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT ,
`count` VARCHAR( 50 ) NOT NULL DEFAULT '',
`month` VARCHAR( 50 ) NOT NULL DEFAULT '',
`amount` VARCHAR( 50 ) NOT NULL DEFAULT '',
`amount2` VARCHAR( 20 ) NOT NULL ,
`type` VARCHAR( 20 ) NOT NULL ,
`date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = latin1";
mysql_query($create);
Then in used the INSERT INTO...SELECT...UNION SELECT....
to select from the expenses and income table to insert into the newly created balance table.
query_merge = "INSERT INTO balance2 (count, date, amount, amount2, month, type)
(SELECT count(*), t.date, sum(t.amount),0 ,monthname(t.date), 'income'
FROM `transaction` as t group by month(t.date))
UNION
(SELECT count(*), e.date, 0,sum(e.amount) as teamount, monthname(e.date) as mne, 'expense'
FROM expenditure as e group by month(e.date))";
this worked perfectly as it gave me all the results i wanted.
Thought it might help someone else. see ya
I am trying to make some sort of SQL Query where I only get the 10 people with the most referrals, but with minimum 1 referral.
My Table looks like this:
CREATE TABLE IF NOT EXISTS `beta_list` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`email` varchar(250) NOT NULL,
`referrer` int(10) NOT NULL,
`referral_code` int(10) NOT NULL,
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
I have tried something like this:
SELECT
email,
referral_code as refcode,
(SELECT COUNT(*) FROM beta_list WHERE referrer=refcode) as referrals
FROM
beta_list
WHERE
referrals > 0
ORDER BY
referrals DESC
LIMIT
10
But it just says "Unknown column 'referrals' in 'where clause'".
I am no sql guru, I am only just beginning to learn more complex sql queries, so any help on how to achieve something like this would be deeply appreciated!
Cheers!
Try this - Add an outer query to extract the results from inner query -
select ref.email, ref.refcode, ref.referrals from
(
SELECT
email,
referral_code as refcode,
(SELECT COUNT(*) FROM beta_list WHERE referrer=refcode) as referrals
FROM
beta_list
) as ref
WHERE
ref.referrals > 0
ORDER BY
ref.referrals DESC
LIMIT
10
Give this a go:
SELECT email,referral_code as refcode,count(*) as referrals
FROM beta_list
WHERE referrer = referral_code
GROUP BY email,referral_code
ORDER BY referrals DESC
LIMIT 10;
Say I have three tables in my database:
CREATE TABLE `users` (
`user_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR(16) NOT NULL
);
CREATE TABLE `users_meta` (
`meta_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_id` INT NOT NULL ,
`key` VARCHAR(200) NOT NULL ,
`value` TEXT NOT NULL
);
CREATE TABLE `posts` (
`post_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_id` INT NOT NULL ,
`content` TEXT NOT NULL
);
The table users_meta is just a key-value store of information about users, such that we can add any piece of information we want.
Say I added a key => value pair to the users_meta table for each user where the key was "age", and the value was a number representing their age.
Given this set of circumstances, what's the best way to select the first 10 posts ordered by user age?
I like putting the condition of the join in the join itself to be clear that I want a limited join:
SELECT p.post_id, p.content
FROM users u
INNER JOIN users_meta um
ON (u.user_id = um.user_id) AND um.key = 'age'
INNER JOIN posts p
ON (p.user_id = u.user_id)
ORDER BY um.value
limit 10
If you order by user age only, you will select 10 posts of the same user (the youngest one).
I would suggest to denormalize and store age in users table directly.
Agree with #KOHb, but if that's exactly what you want, here is the query:
SELECT TOP 10 p.id, p.content
FROM users u JOIN users_meta um ON (u.user_id = um.user_id)
JOIN posts p ON (p.user_id = u.user_id)
WHERE um.key = 'age'
ORDER BY um.value