MySQL Query to display ingredients - mysql

I have the following tables
mysql> select * from drink;
+----+--------------+----------+---------+
| id | name | location | alcohol |
+----+--------------+----------+---------+
| 1 | Ginger Ale | 13 | 0 |
| 2 | Whiskey | 1 | 1 |
| 3 | Vodka | 2 | 1 |
| 4 | Rum | 3 | 1 |
| 5 | Gin | 4 | 1 |
| 6 | Tequila | 5 | 1 |
| 7 | Triple Sec | 6 | 1 |
| 8 | Cola | 14 | 0 |
| 10 | Cherry Vodka | 7 | 1 |
| 11 | Sprite | 15 | 0 |
| 12 | Sour Mix | 0 | 0 |
| 13 | Lemon Juice | 0 | 0 |
| 14 | Lime Juice | 0 | 0 |
| 15 | Grenadine | 0 | 0 |
| 16 | Orange Juice | 16 | 0 |
+----+--------------+----------+---------+
15 rows in set (0.00 sec)
mysql> select * from cocktail;
+----+-------+----------------------------------+
| id | name | comment |
+----+-------+----------------------------------+
| 1 | Item1 | Whiskey Ginger |
| 2 | Item2 | Screwdriver |
| 3 | Item3 | Cherry Vodka and Sprite |
| 4 | Item4 | Bartender's Long Island Iced Tea |
| 5 | Item5 | Long Island Iced Tea |
| 6 | Item6 | Gin and Sin |
+----+-------+----------------------------------+
6 rows in set (0.00 sec)
mysql> select * from mix;
+----+---------+------------+--------+
| id | drinkID | cocktailID | ounces |
+----+---------+------------+--------+
| 1 | 1 | 1 | 4.00 |
| 2 | 2 | 1 | 1.00 |
| 9 | 10 | 3 | 1.00 |
| 10 | 11 | 3 | 4.00 |
| 11 | 5 | 4 | 0.75 |
| 12 | 4 | 4 | 0.75 |
| 13 | 6 | 4 | 0.75 |
| 14 | 3 | 4 | 0.75 |
| 15 | 7 | 4 | 1.00 |
| 16 | 12 | 4 | 1.00 |
| 17 | 8 | 4 | 1.00 |
| 18 | 3 | 5 | 0.75 |
| 19 | 5 | 5 | 0.75 |
| 20 | 4 | 5 | 0.75 |
| 21 | 6 | 5 | 0.75 |
| 22 | 12 | 5 | 2.00 |
| 23 | 8 | 5 | 1.00 |
| 24 | 7 | 5 | 1.00 |
| 25 | 5 | 6 | 2.00 |
| 26 | 13 | 6 | 2.00 |
| 27 | 15 | 6 | 2.00 |
| 28 | 16 | 6 | 2.00 |
| 33 | 3 | 2 | 1.50 |
| 34 | 16 | 2 | 4.00 |
+----+---------+------------+--------+
24 rows in set (0.00 sec)
From these tables I want to create a joined table that has the ID, Comment, Ingredient Name, and Number of ounces.
So far I have this query but I keep getting errors and I am not sure where I am going wrong.
select cocktail.comment
, drink.name
, mix.ounces
from cocktail
join mix
on mix.drinkID = drink.ID
join cocktail
on mix.cocktailID = cocktail.id;
I think that there is something wrong with my join statement but the MySQL error is ambiguous to me
ERROR 1066 (42000): Not unique table/alias: 'cocktail'
Would someone be able to provide me some guidance? Thank you!

You're query is calling the cocktail table twice. If you want to do that you need to use an alias to give unique names to the calls, but it looks like you're missing the JOIN to the drink table. It seems like you want:
select
c.comment,
d.name,
m.ounces
from drink d
inner join mix m
on m.drinkID = d.ID
inner join cocktail c
on m.cocktailID = c.id;
Here is a demo. This difference with this version and your version is it includes a call to the drink table to get the name of the ingredient.

Related

Query the differences between records with same ID

I have a table like this in MS Access 2019:
+-----------+------------+--------+----------+-------+
| BillingID | Date | RoomID | Electric | Water |
+-----------+------------+--------+----------+-------+
| 1 | 12/23/2018 | 4 | 1669 | 106 |
| 2 | 12/26/2018 | 1 | 5035 | 289 |
| 3 | 12/27/2018 | 6 | 0 | 0 |
| 4 | 12/31/2018 | 5 | 3158 | 223 |
| 5 | 1/6/2019 | 2 | 3823 | 194 |
| 6 | 1/15/2019 | 3 | 1772 | 125 |
| 7 | 1/23/2019 | 4 | 1796 | 117 |
| 8 | 1/26/2019 | 1 | 5231 | 299 |
| 9 | 1/27/2019 | 6 | 0 | 0 |
| 10 | 1/31/2019 | 5 | 3366 | 242 |
| 11 | 2/14/2019 | 2 | 3975 | 201 |
| 12 | 2/15/2019 | 3 | 1839 | 129 |
+-----------+------------+--------+----------+-------+
I could calculate the electricity and water usage with Index & Match in MS Excel. However, I've had a lot of trouble to achieve this with MS Access. The result I want is as below:
+-----------+------------+--------+----------+---------------+-------+------------+
| BillingID | Date | RoomID | Electric | ElectricUsage | Water | WaterUsage |
+-----------+------------+--------+----------+---------------+-------+------------+
| 1 | 12/23/2018 | 4 | 1669 | | 106 | |
| 2 | 12/26/2018 | 1 | 5035 | | 289 | |
| 3 | 12/27/2018 | 6 | 0 | | 0 | |
| 4 | 12/31/2018 | 5 | 3158 | | 223 | |
| 5 | 1/6/2019 | 2 | 3823 | | 194 | |
| 6 | 1/15/2019 | 3 | 1772 | | 125 | |
| 7 | 1/23/2019 | 4 | 1796 | 127 | 117 | 11 |
| 8 | 1/26/2019 | 1 | 5231 | 196 | 299 | 10 |
| 9 | 1/27/2019 | 6 | 0 | | 0 | |
| 10 | 1/31/2019 | 5 | 3366 | 208 | 242 | 19 |
| 11 | 2/14/2019 | 2 | 3975 | 152 | 201 | 7 |
| 12 | 2/15/2019 | 3 | 1839 | 67 | 129 | 4 |
+-----------+------------+--------+----------+---------------+-------+------------+
For example, for RoomID = 4, the ElectricUsage is the difference between the Electric in BillingID #7 and BillingID #1 and so on.
I've tried some answer like this or this but Access ran into errors when using those solutions in SQL view (Syntax error in FROM clause).
Thanks.
You can use a couple of sub-queries to return the Electric/Water for each room on the previous date:
SELECT
B.BillingID, B.BillingDate, B.RoomID, B.Electric,
B.Electric-(SELECT TOP 1 E.Electric FROM tblBilling AS E WHERE B.RoomID=E.RoomID AND E.BillingDate<B.BillingDate ORDER BY E.BillingDate DESC) AS ElectricUsage,
B.Water,
B.Water-(SELECT TOP 1 W.Water FROM tblBilling AS W WHERE B.RoomID=W.RoomID AND W.BillingDate<B.BillingDate ORDER BY W.BillingDate DESC) AS WaterUsage
FROM tblBilling AS B
Note that I've renamed your Date field to be BillingDate, as Date is a reserved word in Access, and will cause you problems in the future.
Regards,

How to merge tables in MySQL, although not just an outright merge?

I have three tables titled 'artist', 'album', and 'track' in MySQL, each containing information pertaining to my music library. 'artist' has the name of 4 artists, 'album' has the titles of 5 albums from those artists, and 'track' has the name of all tracks on said albums. I would like to combine the tables so the each track name has beside it the correct album title and artist name. Here are my tables:
artist
+-----------+-----------------+
| artist_id | artist_name |
+-----------+-----------------+
| 1 | Kacey Musgraves |
| 2 | The Lone Bellow |
| 3 | Ed Sheeran |
| 4 | The Civil Wars |
+-----------+-----------------+
album
+-----------+----------+-----------------------+
| artist_id | album_id | album_name |
+-----------+----------+-----------------------+
| 1 | 1 | Pageant Material |
| 2 | 1 | Then Came the Morning |
| 3 | 1 | + |
| 3 | 2 | x |
| 4 | 1 | The Civil Wars |
+-----------+----------+-----------------------+
track
+-----------+----------+----------+-------------------------------+------------+
| artist_id | album_id | track_id | track_name | track_time |
+-----------+----------+----------+-------------------------------+------------+
| 1 | 1 | 1 | Makin' Music for Money | 2.97 |
| 1 | 1 | 2 | Dime Store Cowgirl | 3.58 |
| 1 | 1 | 3 | Late to the Party | 3.63 |
| 1 | 1 | 4 | Pageant Material | 3.90 |
| 1 | 1 | 5 | This Town | 2.95 |
| 1 | 1 | 6 | Biscuits | 3.28 |
| 1 | 1 | 7 | Somebody to Love | 3.22 |
| 1 | 1 | 8 | Miserable | 3.00 |
| 1 | 1 | 9 | Die Fun | 3.47 |
| 1 | 1 | 10 | Family is Family | 2.53 |
| 1 | 1 | 11 | Good Ol' Boys Club | 3.27 |
| 1 | 1 | 12 | Cup of Tea | 2.67 |
| 1 | 1 | 13 | Fine | 7.88 |
| 2 | 1 | 1 | Then Came the Morning | 4.01 |
| 2 | 1 | 2 | Fake Roses | 3.57 |
| 2 | 1 | 3 | Marietta | 3.57 |
| 2 | 1 | 4 | Take My Love | 3.25 |
| 2 | 1 | 5 | Call to War | 3.47 |
| 2 | 1 | 6 | Watch Over Us | 3.57 |
| 2 | 1 | 7 | Diners | 4.40 |
| 2 | 1 | 8 | Heaven Don't Call Me Home | 2.60 |
| 2 | 1 | 9 | If You Don't Love Me | 3.23 |
| 2 | 1 | 10 | Telluride | 4.28 |
| 2 | 1 | 11 | To the Woods | 2.00 |
| 2 | 1 | 12 | Cold As It Is | 2.93 |
| 2 | 1 | 13 | I Let You Go | 3.42 |
| 3 | 1 | 1 | The A Team | 4.66 |
| 3 | 1 | 2 | Drunk | 4.32 |
| 3 | 1 | 3 | U.N.I. | 3.82 |
| 3 | 1 | 4 | Grade 8 | 3.00 |
| 3 | 1 | 5 | Wake Me Up | 3.83 |
| 3 | 1 | 6 | Small Bump | 4.32 |
| 3 | 1 | 7 | This | 3.27 |
| 3 | 1 | 8 | The City | 3.90 |
| 3 | 1 | 9 | Lego House | 3.08 |
| 3 | 1 | 10 | You Need Me, I Don't Need You | 3.67 |
| 3 | 1 | 11 | Kiss Me | 4.68 |
| 3 | 1 | 12 | Give Me Love | 8.77 |
| 3 | 2 | 1 | One | 4.22 |
| 3 | 2 | 2 | I'm A Mess | 4.08 |
| 3 | 2 | 3 | Sing | 3.92 |
| 3 | 2 | 4 | Don't | 3.67 |
| 3 | 2 | 5 | Nina | 3.77 |
| 3 | 2 | 6 | Photograph | 4.32 |
| 3 | 2 | 7 | Bloodstream | 5.00 |
| 3 | 2 | 8 | Tenerife Sea | 4.02 |
| 3 | 2 | 9 | Runaway | 3.42 |
| 3 | 2 | 10 | The Man | 4.17 |
| 3 | 2 | 11 | Thinking Out Loud | 4.70 |
| 3 | 2 | 12 | Afire Love | 5.23 |
| 3 | 2 | 13 | Take It BAck | 3.47 |
| 3 | 2 | 14 | Shirtsleeves | 3.17 |
| 3 | 2 | 15 | Even My Dad Does Sometimes | 3.82 |
| 3 | 2 | 16 | I See Fire | 4.98 |
| 4 | 1 | 1 | The One That Got Away | 3.55 |
| 4 | 1 | 2 | I Had Me a Girl | 3.75 |
| 4 | 1 | 3 | Same Old Same Old | 3.80 |
| 4 | 1 | 4 | Dust to Dust | 3.83 |
| 4 | 1 | 5 | Eavesdrop | 3.58 |
| 4 | 1 | 6 | Devil's Backbone | 2.48 |
| 4 | 1 | 7 | From This Valley | 3.55 |
| 4 | 1 | 8 | Tell Mama | 3.80 |
| 4 | 1 | 9 | Oh Henry | 3.55 |
| 4 | 1 | 10 | Disarm | 4.70 |
| 4 | 1 | 11 | Sacred Heart | 3.32 |
| 4 | 1 | 12 | D'Arline | 3.10 |
+-----------+----------+----------+-------------------------------+------------+
In 'track' each number under artist_id corresponds to the same numbered entry in 'artist', and the same goes for album_id and 'album'. Basically, I want to create a new table with every track in 'track', along with its respective album and artist.Any help would be appreciated!
Use JOIN in your SELECT query, like,
select * from track_name
join artist_name on track_name.artist_id = artist_name.artist_id
join album_name on track_name.album_id = album_name.album_id;
Now if you want this in new table you can insert this records in that table, or better if you want to run above query multiple time then you can create a VIEW.
MySQL Views
That sounds like a very basic join
select *
from track_name
join artist_name using (artist_id)
join album_name using (album_id)
I am writing this query by hoping there would be columns album_id and artist_id in the respective tables.
I also suggest you to change the column name track_name so to avoid conflict between table name and column name.
SELECT *
FROM `track_name` t1
LEFT JOIN `artist_name` a1 ON t1.`artist_id`=a1.`artist_id`
LEFT JOIN `album_name` a2 ON t1.`album_name`=a2.`album_name`
GROUP BY t1.`track_name`;

SQL joining three tables and split into columns

I have three tables, mess_stock, mess_voucher, add_grocery.
Mess_stock table is below,
+-----+------------+-----------------+-----------------+--------+---------+---------+------------+----------+
| sno | voucher_id | particular_name | opening_balance | inward | outward | balance | pay_amount | pay_type |
+-----+------------+-----------------+-----------------+--------+---------+---------+------------+----------+
| 49 | 5 | 4 | 100 | 10 | 100 | 10 | 10.00 | 1 |
| 50 | 17 | 5 | 111 | 10 | 20 | 101 | 60.00 | 1 |
| 51 | 7 | 3 | 123 | 2 | 1 | 124 | 300.00 | 1 |
| 52 | 7 | 1 | 123 | 20 | 20 | 123 | 500.00 | 2 |
| 53 | 14 | 8 | 100 | 5 | 95 | 10 | 60.00 | 2 |
+-----+------------+-----------------+-----------------+--------+---------+---------+------------+----------+
Mess_voucher table is below
+------------+--------------+--------------+
| voucher_id | voucher_name | voucher_date |
+------------+--------------+--------------+
| 5 | VG1001 | 2015-02-19 |
| 6 | VG1001 | 2015-02-20 |
| 7 | VG1002 | 2015-02-20 |
| 8 | VG1002 | 2015-02-19 |
| 9 | MS1001 | 2015-02-20 |
| 10 | VG10012 | 2015-02-19 |
| 11 | 0 | 2015-02-23 |
| 12 | 1 | 2015-02-24 |
| 13 | MS1001 | 2015-02-25 |
| 14 | MS1001 | 2015-02-28 |
| 15 | VG1003 | 2015-02-28 |
| 16 | MS1001 | 2015-02-19 |
| 17 | MS1001 | 2015-02-21 |
+------------+--------------+--------------+
Add_grocery table is below
+-----+-----------------+------------------+
| sno | particular_name | particular_price |
+-----+-----------------+------------------+
| 1 | Rice | 25.00 |
| 3 | Mango | 150.00 |
| 4 | Coconut | 22.00 |
| 5 | Banana | 6.00 |
| 6 | Raddish | 12.00 |
| 7 | Apple | 150.00 |
| 8 | Pumkin | 12.00 |
+-----+-----------------+------------------+
I want to group the sum of pay_amount of mess_stock table. I have used the below query
SELECT opening_balance AS ope_stock,
balance AS clo_stock,
SUM(IF(pay_type = 1, pay_amount, 0)) mess_pay,
SUM(IF(pay_type=2, pay_amount, 0)) est_pay
FROM mess_stock;
That works fine. The particular_name is the auto increment id of add_grocery table. I need the inward outward amount total. For example the inward amount 10 means it has to get the particular_price from add_grocery using the particular_name provided in the mess_stock table, similarly I need all the answer. And I want to sort that by date wise. The date of the entry is stored in the mess_voucher table that is connected to mess_stock table.
Try this it will work :
Use Inner Join :
SELECT t2.`particular_name`,t1.`inward`,t1.`outward`,t2.`particular_price`,t3.`voucher_date` from Mess_stock t1 JOIN Add_grocery t2 ON t1.`particular_name`=t2.`sno` JOIN Mess_voucher t3 ON t3.`voucher_id`=t1.`voucher_id` ORDER BY t3.`voucher_date` DESC

fetching required data using joins in mysql

My tables :
mysql> select * from professor;
+-------+--------+--------+--------+------+
| empid | name | status | salary | age |
+-------+--------+--------+--------+------+
| 1 | Arun | 1 | 2000 | 23 |
| 2 | Benoy | 0 | 3000 | 25 |
| 3 | Chacko | 1 | 1000 | 36 |
| 4 | Divin | 0 | 5000 | 32 |
| 5 | Edwin | 1 | 2500 | 55 |
| 7 | George | 0 | 1500 | 46 |
+-------+--------+--------+--------+------+
6 rows in set (0.00 sec)
mysql> select * from works;
+----------+-------+---------+
| courseid | empid | classid |
+----------+-------+---------+
| 1 | 1 | 10 |
| 2 | 2 | 9 |
| 3 | 3 | 8 |
| 4 | 4 | 10 |
| 5 | 5 | 9 |
| 6 | 1 | 9 |
| 2 | 3 | 10 |
| 2 | 1 | 7 |
| 4 | 2 | 6 |
| 2 | 4 | 6 |
| 2 | 5 | 2 |
| 7 | 5 | 6 |
| 3 | 5 | 2 |
| 6 | 4 | 10 |
+----------+-------+---------+
14 rows in set (0.00 sec)
mysql> select * from course;
+----------+------------+--------+
| courseid | coursename | points |
+----------+------------+--------+
| 1 | Maths | 5 |
| 2 | Science | 1 |
| 3 | English | 6 |
| 4 | Social | 4 |
| 5 | Malayalam | 20 |
| 6 | Arts | 25 |
| 7 | Biology | 20 |
+----------+------------+--------+
7 rows in set (0.00 sec)
Question is :
Return the name(s) of the professor(s) who taught the most number of
courses in Class 10
Query i tried is :
select professor.name,works.courseid,works.empid,works.classid from professor
inner join works
on professor.empid=works.empid
where works.classid=10
group by works.courseid
I know its imcomplete/incorrect. Pls help me to the required result.
select
professor.name, count(works.courseid)
from
works
inner join
professor on
professor.empid = works.empid
where
work.classid = 10
group by
professor.name
order by count(works.courseid) desc
limit 1
change this in your select statment
works.courseid
to
count(works.courseid) as courseid

How to duplicate row and generate not duplicate ID in mysql

I am using mysql and need to duplicate all row in my table but I do not duplicate id column and new generate number
need ex.
my table
item_db
+------------------------------------------+
| id | name | price | detail |
+------------------------------------------+
| 1 | example | 230 | 3 |
| 2 | power | 110 | 3 |
| 3 | voltage | 1.2 | 4 |
| 4 | example | 240 | 4 |
| 5 | example | 320 | 6 |
| 6 | power | 100 | 4 |
| 7 | power | 110 | 6 |
| 8 | example | 230 | 3 |
| 9 | power | 110 | 3 |
| 10 | voltage | 1.2 | 4 |
| 20 | example | 240 | 4 |
| 21 | example | 320 | 6 |
| 22 | power | 100 | 4 |
| 23 | power | 110 | 6 |
| 24 | example | 240 | 4 |
| 25 | example | 320 | 6 |
| 26 | power | 100 | 4 |
| 27 | power | 110 | 6 |
| 28 | example | 240 | 4 |
| 29 | example | 320 | 6 |
| 30 | power | 100 | 4 |
+------------------------------------------+
i need to duplicate
item_db
+------------------------------------------+
| id | name | price | detail |
+------------------------------------------+
| 1 | example | 230 | 3 |
| 2 | power | 110 | 3 |
| 3 | voltage | 1.2 | 4 |
| 4 | example | 240 | 4 | I need to dup id 1-10 to 101-110
| 5 | example | 320 | 6 |
| 6 | power | 100 | 4 |
| 7 | power | 110 | 6 |
| 8 | example | 230 | 3 |
| 9 | power | 110 | 3 |
| 10 | voltage | 1.2 | 4 |
| 101| example | 230 | 3 |
| 102| power | 110 | 3 |
| 103| voltage | 1.2 | 4 |
| 104| example | 240 | 4 |
| 105| example | 320 | 6 |
| 106| power | 100 | 4 |
| 107| power | 110 | 6 |
| 108| example | 230 | 3 |
| 109| power | 110 | 3 |
| 110| voltage | 1.2 | 4 |
| 20 | example | 240 | 4 |
| 21 | example | 320 | 6 |
| 22 | power | 100 | 4 |
| 23 | power | 110 | 6 |
| 24 | example | 240 | 4 |
| 25 | example | 320 | 6 |
| 26 | power | 100 | 4 | i need to dup 20-30 to 200-210
| 27 | power | 110 | 6 |
| 28 | example | 240 | 4 |
| 29 | example | 320 | 6 |
| 30 | power | 100 | 4 |
| 200| example | 240 | 4 |
| 201| example | 320 | 6 |
| 202| power | 100 | 4 |
| 203| power | 110 | 6 |
| 204| example | 240 | 4 |
| 205| example | 320 | 6 |
| 206| power | 100 | 4 |
| 207| power | 110 | 6 |
| 208| example | 240 | 4 |
| 209| example | 320 | 6 |
| 210| power | 100 | 4 |
+------------------------------------------+
thanks you expert.
You can use INSERT ... SELECT:
INSERT INTO item_db (id, name, price, detail)
SELECT id+180, name, price, detail FROM item_db WHERE id BETWEEN 20 AND 30
How exactly you want to treat id is not entirely clear. If, for example, you wish to automatically assign AUTO_INCREMENT values, then you can (as usual) omit it from the INSERT statement.