Issue while joining many tables - mysql

I have four tables :
products sizes
----------------------------- -----------------------------------
| product_id | product_name | | pizza_size_id | pizza_size_name |
----------------------------- -----------------------------------
| 39 | Italyan | | 1 | Small |
| 40 | Classic | | 2 | Medium |
| 41 | Lamb | | 3 | Large |
| 42 | Evi | -----------------------------------
-----------------------------
menu_details
--------------------------------------------------------
| id | order_details_fk | pizza_menus_fk | products_fk |
--------------------------------------------------------
| 17 | 132 | 92 | 39 |
| 18 | 132 | 92 | 40 |
| 19 | 132 | 92 | 41 |
| 20 | 132 | 92 | 42 |
--------------------------------------------------------
pizza_menus
--------------------------
| id | menu_id | size_id |
--------------------------
| 25 | 92 | 1 |
| 26 | 92 | 1 |
| 27 | 92 | 1 |
| 28 | 92 | 2 |
--------------------------
This is my SQL code :
SELECT DISTINCT products.product_name, sizes.pizza_size_name
FROM products, menu_details, pizza_menus, sizes
WHERE products.product_id = menu_details.products_fk
AND menu_details.pizza_menus_fk = pizza_menus.menu_id
AND pizza_menus.size_id = sizes.pizza_size_id
AND menu_details.order_details_fk = 132
My desired output
----------------------------------
| product_name | pizza_size_name |
----------------------------------
| Italyan | Small |
| Classic | Small |
| Lamb | Small |
| Evi | Medium |
----------------------------------
Output that I get
----------------------------------
| product_name | pizza_size_name |
----------------------------------
| Italyan | Small |
| Classic | Small |
| Lamb | Small |
| Evi | Small |
| Italyan | Medium |
| Classic | Medium |
| Lamb | Medium |
| Evi | Medium |
----------------------------------
I know too many tables for such easy question but anyways
I really appreciate your help, thank you!

Associations between menu_details and pizza_menu were made wrong so I chaged menu_details to :
--------------------------------------------------------
| id | order_details_fk | pizza_menus_fk | products_fk |
--------------------------------------------------------
| 17 | 132 | 25 | 39 |
| 18 | 132 | 26 | 40 |
| 19 | 132 | 27 | 41 |
| 20 | 132 | 28 | 42 |
--------------------------------------------------------
And here is my new SQL:
SELECT DISTINCT products.product_name, sizes.pizza_size_name
FROM products, menu_details, pizza_menus, sizes
WHERE products.product_id = menu_details.products_fk
AND menu_details.pizza_menus_fk = pizza_menus.id
AND pizza_menus.size_id = sizes.pizza_size_id
AND menu_details.order_details_fk = 132

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,

Is there a way to grab associated data from three different tables and display them?

I have four tables, three of which I need data from, as well as a fourth that stores how this data is associated. When running my query, I'm getting the wrong output and it seems like I'm not linking things up correctly, but I'm unsure as to how to do so. How do I link my joins to get the output I'm looking for?
So far, I've used
SELECT c.class, p.name, s.specialization
FROM players_classes pc
JOIN players p ON p.player_id=pc.player_id
JOIN classes c ON c.class_id=pc.class_id
JOIN specialization s ON s.spec_id=pc.spec_id
which references
CREATE TABLE players(
player_id INT UNSIGNED auto_increment PRIMARY KEY,
name VARCHAR(20)
)...;
CREATE TABLE classes(
class_id INT UNSIGNED auto_increment PRIMARY KEY,
class VARCHAR(20)
)...;
CREATE TABLE specializations(
spec_id INT UNSIGNED auto_increment PRIMARY KEY,
class_id INT UNSIGNED,
specialization VARCHAR(20)
)...;
but I'd like to be using this table in some way to display the information correctly linked, I'm just unsure how to do so:
CREATE TABLE players_classes(
pc_id INT UNSIGNED auto_increment PRIMARY KEY,
FOREIGN KEY(class_id) REFERENCES classes(class_id),
FOREIGN KEY(player_id) REFERENCES players(player_id),
FOREIGN KEY(spec_id) REFERENCES specializations(spec_id)
)...;
I'm expecting to be able to grab a player's name as well as their associated class and specialization, actual results are showing the values associated with 1/1/1 for each id, and so on and so forth.
edit: the data from players_classes is as follows
pc_id | class_id | player_id | spec_id |
1 3 1 8
2 12 2 35
3 2 3 6
etc.
therefore the expected result from this is
class | name | spec
paladin seranul holypa
hunter contherious marksmanship
priest unicorns holypr
I am instead getting
class | name | spec
warlock Affliction Affliction
warlock Grireaver Demonology
warlock Affliction Demonology
and so on throughout the table, listing combinations that do not exist within my players_classes table
specializations table
+---------+----------+----------------+
| spec_id | class_id | specialization |
+---------+----------+----------------+
| 1 | 1 | Affliction |
| 2 | 1 | Destruction |
| 3 | 1 | Demonology |
| 4 | 2 | Shadow |
| 5 | 2 | Discipline |
| 6 | 2 | HolyPr |
| 7 | 3 | Retribution |
| 8 | 3 | HolyPa |
| 9 | 3 | ProtectionPa |
| 10 | 4 | ProtectionWa |
| 11 | 4 | Arms |
| 12 | 4 | Fury |
| 13 | 5 | FrostMa |
| 14 | 5 | Fire |
| 15 | 5 | Arcane |
| 16 | 6 | vengeance |
| 17 | 6 | havoc |
| 18 | 7 | guardian |
| 19 | 7 | balance |
| 20 | 7 | feral |
| 21 | 7 | restorationDr |
| 22 | 8 | elemental |
| 23 | 8 | enhance |
| 24 | 8 | restorationSh |
| 25 | 9 | frostDk |
| 26 | 9 | blood |
| 27 | 9 | unholy |
| 28 | 10 | outlaw |
| 29 | 10 | assassin |
| 30 | 10 | subtlety |
| 31 | 11 | brewmaster |
| 32 | 11 | windwalker |
| 33 | 11 | mistweaver |
| 34 | 12 | BeastMaster |
| 35 | 12 | marksmanship |
| 36 | 12 | Survival |
+---------+----------+----------------+
classes table
+----------+-------------+
| class_id | class |
+----------+-------------+
| 1 | warlock |
| 2 | priest |
| 3 | paladin |
| 4 | warrior |
| 5 | mage |
| 6 | demonhunter |
| 7 | druid |
| 8 | shaman |
| 9 | deathknight |
| 10 | rogue |
| 11 | monk |
| 12 | hunter |
+----------+-------------+
players table
+-----------+--------------+
| player_id | name |
+-----------+--------------+
| 1 | Seranul |
| 2 | Contherious |
| 3 | Unicorns |
| 4 | Remereili |
| 5 | Affliction |
| 6 | Meowing |
| 7 | Brobot |
| 8 | Bagelsbbq |
| 9 | Rafusen |
| 10 | Taiboku |
| 11 | Yikes |
| 12 | Thunderblaze |
| 13 | Muo |
| 14 | Intz |
| 15 | Trunks |
| 16 | Kalphyte |
| 17 | Eyeoftheshoe |
| 18 | Amuhnet |
| 19 | Synkka |
| 20 | Affliction |
| 21 | Kts |
| 22 | Shadowdreams |
| 23 | Zahel |
| 24 | Azrama |
| 25 | Seranul |
| 26 | Momspaghetti |
| 27 | Ohki |
| 28 | Rafusen |
| 29 | Cindyy |
| 30 | Grireaver |
| 31 | Intz |
| 32 | lazy |
| 33 | missworld |
| 34 | Affliction |
| 35 | Amuhnet |
| 36 | eyeoftheshoe |
| 37 | sanctus |
| 38 | nozshelen |
| 39 | Contherious |
| 40 | messer |
| 41 | catathor |
| 42 | demonblaze |
| 43 | wrillett |
| 44 | raagnnar |
| 45 | xizi |
| 46 | nemesix |
| 47 | zeroskill |
| 48 | chikfillidan |
| 49 | tentenlol |
| 50 | unicorns |
| 51 | bubuhtide |
| 52 | ohki |
| 53 | azrama |
+-----------+--------------+
players_classes table
+-------+----------+-----------+---------+
| pc_id | class_id | player_id | spec_id |
+-------+----------+-----------+---------+
| 1 | 3 | 1 | 8 |
| 2 | 12 | 2 | 35 |
| 3 | 2 | 3 | 6 |
| 4 | 11 | 4 | 31 |
| 5 | 1 | 5 | 1 |
| 6 | 12 | 6 | 34 |
| 7 | 2 | 7 | 6 |
| 8 | 11 | 8 | 31 |
| 9 | 2 | 9 | 6 |
| 10 | 7 | 10 | 21 |
| 11 | 4 | 11 | 11 |
| 12 | 8 | 12 | 22 |
| 13 | 4 | 13 | 12 |
| 14 | 5 | 14 | 13 |
| 15 | 3 | 15 | 7 |
| 16 | 11 | 16 | 33 |
| 17 | 8 | 17 | 22 |
| 18 | 2 | 18 | 6 |
| 19 | 8 | 19 | 23 |
| 20 | 11 | 20 | 33 |
| 21 | 5 | 21 | 13 |
| 22 | 6 | 22 | 17 |
| 23 | 10 | 23 | 29 |
| 24 | 8 | 24 | 22 |
| 25 | 11 | 25 | 31 |
| 26 | 11 | 26 | 32 |
| 27 | 4 | 27 | 11 |
| 28 | 5 | 28 | 13 |
| 29 | 7 | 29 | 19 |
| 30 | 1 | 30 | 3 |
| 31 | 9 | 31 | 25 |
| 32 | 3 | 32 | 8 |
| 33 | 9 | 33 | 25 |
| 34 | 1 | 34 | 3 |
| 35 | 2 | 35 | 6 |
| 36 | 4 | 36 | 11 |
| 37 | 5 | 37 | 13 |
| 38 | 5 | 38 | 13 |
| 39 | 9 | 39 | 25 |
| 40 | 6 | 40 | 17 |
| 41 | 10 | 41 | 28 |
| 42 | 2 | 42 | 6 |
| 43 | 8 | 43 | 24 |
+-------+----------+-----------+---------+
You need to use the relationship table in your query:
SELECT c.class, p.name, s.specialization
FROM players_classes pc
JOIN players p ON p.player_id = pc.player_id
JOIN classes c ON c.class_id = pc.class_id
JOIN specializations s ON s.spec_id = pc.spec_id
DEMO
You shouldn't even have class_id and spec_id in the other tables, since these are many-to-many relationships, and those columns can only be used for one-to-one relationships.

not able to fetch date value using subqueries mysql

i have two tables called
1 table smartpos.pos_order_Id
+---------+--------------+---------+--------+--------------+----------------+------------+
| orderId | restaurantId | tableId | closed | customerName | customerNumber | dateorderd |
+---------+--------------+---------+--------+--------------+----------------+------------+
| 7 | 14 | 0 | yes | | | 21/03/2018 |
| 8 | 14 | 0 | yes | | | 21/03/2018 |
| 9 | 14 | 0 | no | | | 20/03/2018 |
| 10 | 14 | 0 | yes | soumya | 1234567890 | 21/03/2018 |
| 11 | 14 | 0 | yes | | | 21/03/2018 |
| 12 | 14 | 0 | yes | | | 21/03/2018 |
| 13 | 14 | 0 | yes | | | 21/03/2018 |
| 14 | 14 | 0 | yes | | | 20/03/2018 |
| 15 | 14 | 0 | no | | | 22/03/2018 |
+---------+--------------+---------+--------+--------------+----------------+------------+
2smartpos.pos_invoice
+---------------+---------+----------+-------------+-------------+------------+-------------+---------------+
| invoiceNumber | orderId | totalAmt | discountAmt | totalTaxAmt | grandTotal | paymentmode | paymentrefNum |
+---------------+---------+----------+-------------+-------------+------------+-------------+---------------+
| 1 | 7 | 200 | 34 | 46 | 212 | Cash | |
| 2 | 10 | 1200 | 200 | 280 | 1280 | Cash | |
| 3 | 1 | 720 | 34 | 120 | 806 | Cash | |
| 4 | 12 | 240 | 34 | 58 | 264 | Cash | |
| 5 | 13 | 330 | 32 | 83 | 381 | Cash | |
| 6 | 14 | 80 | 2 | 22 | 100 | Cash | |
+---------------+---------+----------+-------------+-------------+------------+-------------+---------------+
i want to fetch invoice details using restaurantId and two dates by providing restaurantId and dates as follows
select inv.invoiceNumber ,inv.totalAmt,inv.discountAmt,inv.totalTaxAmt,inv.grandTotal,i.dateorderd from smartpos.pos_invoice inv,smartpos.pos_order_Id i where inv.invoiceNumber in (select invv.invoiceNumber from smartpos.pos_invoice invv where invv.orderId in(select ii.orderId from smartpos.pos_order_Id ii where ii.closed='yes' and ii.restaurantId=14 and STR_TO_DATE(dateorderd,'%d/%m/%Y') between STR_TO_DATE('20/03/2018','%d/%m/%Y') and STR_TO_DATE('21/03/2018','%d/%m/%Y'))) group by inv.invoiceNumber ;
out put:
+---------------+----------+-------------+-------------+------------+------------+
| invoiceNumber | totalAmt | discountAmt | totalTaxAmt | grandTotal | dateorderd |
+---------------+----------+-------------+-------------+------------+------------+
| 1 | 200 | 34 | 46 | 212 | NULL |
| 2 | 1200 | 200 | 280 | 1280 | NULL |
| 4 | 240 | 34 | 58 | 264 | NULL |
| 5 | 330 | 32 | 83 | 381 | NULL |
| 6 | 80 | 2 | 22 | 100 | NULL |
+---------------+----------+-------------+-------------+------------+------------+
but when i run above query it gives null values , how to fetch the date as well?
Its difficult to understand what you wrote but i think you query is much simple than it seems, try to use this approach :
select
inv.invoiceNumber ,
inv.totalAmt,
inv.discountAmt,
inv.totalTaxAmt,
inv.grandTotal,
i.dateorderd
from
smartpos.pos_invoice inv,
smartpos.pos_order_Id i
where
inv.orderId = i.orderId
and
i.closed='yes'
and
i.restaurantId=14
and
STR_TO_DATE(dateorderd,'%d/%m/%Y') between STR_TO_DATE('20/03/2018','%d/%m/%Y') and STR_TO_DATE('21/03/2018','%d/%m/%Y')
group by
inv.invoiceNumber;

convert rows into coumns dinamiacally for some table with CONCAT and GROUP_CONCAT mysql query

by followed Mysql query to dynamically convert rows to columns on the basis of two columns,
I have 4 table to convert dinamiacally rows into columns as RESULT
TABLE A
| id | stages |
-----+----------
| 1 | Stage A |
| 2 | Stage B |
| 3 | Stage C |
TABLE B
| id_b | code | lessons |
-------+------+--------------
| 10 | FIS | Physics |
| 11 | MAT | Mathematics |
| 12 | KIM | Chemistry |
| 13 | BIO | Biology |
TABLE C
|id_c| students |
-----+-------------
| 20 | student 20 |
| 21 | student 21 |
| 22 | student 22 |
| 23 | student 23 |
| 24 | student 24 |
| 25 | student 25 |
| 26 | student 26 |
| 27 | student 27 |
TABLE D
| id_d | id_a | id_b | id_c | value_m | value_n |
-------+------+------+------+---------+----------
| 201 | 1 | 11 | 20 | 71 | 73 |
| 203 | 1 | 13 | 20 | 80 | 87 |
| 204 | 2 | 10 | 21 | 72 | 75 |
| 206 | 2 | 13 | 21 | 76 | 78 |
| 208 | 2 | 12 | 22 | 72 | 78 |
| 209 | 2 | 13 | 22 | 76 | 80 |
| 210 | 3 | 11 | 23 | 73 | 71 |
| 211 | 3 | 12 | 23 | 71 | 77 |
| 212 | 3 | 13 | 23 | 78 | 81 |
| 213 | 3 | 10 | 24 | 70 | 81 |
| 214 | 3 | 11 | 25 | 71 | 82 |
| 215 | 3 | 12 | 26 | 74 | 83 |
| 215 | 3 | 13 | 27 | 78 | 80 |
RESULT
| students | FIS_1 | MAT_1 | KIM_1 | BIO_1 | FIS_2 | MAT_2 | KIM_2 | BIO_2 | FIS_3 | MAT_3 | KIM_3 | BIO_3 |
-------------+-------+-------+-------+-------+--------+------+-------+-------+-------+-------+-------+--------
| student 20 | | 71,73 | | 80,87 | | | | | | | | |
| student 21 | | | | | 72,75 | 76,78 | | | | | | |
| student 22 | | | | | | | 72,78 | 76,80 | | | | |
| student 23 | | | | | | | | | | 73,71 | 71,77 | 78,81 |
| student 24 | | | | | | | | | 70,81 | | | |
| student 25 | | | | | | | | | | 71,82 | | |
| student 26 | | | | | | | | | | | 74,83 | |
| student 27 | | | | | | | | | | | | 78,80 |
Where FIS_1, MAT_1,... FIS_2, MAT_2.., FIS_3, MAT_3.. is CONCAT from TABLE B kode and TABLE A id,
and value MAT_1, BIO_1... is CONCAT from TABLE D value_m and value_n
It's Posible? How can I do that with GROUP_CONCAT mysql query? I've tried it but still not successful..
Thanks for your advance..

mysql group_concat comma separated ids to match names

I wrote this query to find the list of shops selling what categories.
SELECT GROUP_CONCAT(distinct(sub_category_id)) AS s,
vendor_id AS v
FROM link_products_lists_vendors
GROUP BY vendor_id;
This results in,
+---------------------------------------+------------+
| category_ids | vendor_ids |
+---------------------------------------+------------+
| 24,28,25,16,26,23,27,2 | 3 |
| 2 | 67 |
| 19,28,17,16,20,2 | 68 |
| 19,28,24,26,23,21,16,27,22,17,25,2 | 122 |
| 16,2 | 123 |
| 28,17,22,21,18,16,26,27,20,23,25,2 | 124 |
| 22,19,21,20,16,24,28,25,23,26,2 | 125 |
| 23,24,26,25,28,16,20,27,19,2 | 126 |
| 19,26,28,18,20,27,22,16 | 127 |
| 22,26,28,21,23,20,24,19,16,17,27,25,2 | 128 |
| 2 | 129 |
| 2 | 133 |
| 19,20,28,16,27,25,21,23,26,24,22 | 135 |
| 23,28,17,22,26,21,16,20,27,24,25,2 | 136 |
| 19,17,16,21,23,26,22,25,27,20,28 | 137 |
| 19,20,26,22,21,24,23,17,28,16,27,25,2 | 138 |
| 19,20,23,28,26,21,24,16,27,22,25,17,2 | 139 |
| 22,27,20,21,24,17,23,28,26,19,25,2 | 142 |
| 19,28,17,20,2 | 143 |
+---------------------------------------+------------+
19 rows in set (0.01 sec)
What I want now is something like,
+-------------------------- -----------+--- ----------+
| category_names | vendor_names |
+---------------------------------------+--------------+
| mobiles,laptops,desktops | abcShop |
| mobiles | xyzShop |
| desktops,mouses,keyboards | pqrShop |
+---------------------------------------+--------------+
I have the categories table as,
+----+---------------+
| id | name |
+----+---------------+
| 17 | desktops |
| 18 | external_hdds |
| 26 | headphones |
| 27 | headsets |
| 22 | keyboards |
| 16 | laptops |
| 24 | memory_cards |
| 2 | mobile-phones |
| 21 | mouses |
| 25 | pendrives |
| 19 | printers |
| 20 | routers |
| 23 | speakers |
| 28 | tablets |
+----+---------------+
Vendors table as,
+-----+----------------------+
| id | name |
+-----+----------------------+
| 108 | abcShop |
| 109 | xyzShop |
| 45 | pqrShop |
| 89 | . |
| 63 | . |
| 64 | . |
+-----+----------------------+
How should I write a query that will not display ids but use the table that displays ids and displays names? I have no clue from where to start this. Please help!
Just join in the other tables and select those values instead
SELECT GROUP_CONCAT(distinct(c.name)) AS s,
v.name AS v
FROM link_products_lists_vendors l
JOIN categories c on l.category_id = c.id
JOIN vendors v on l.vendor_id = v.id
GROUP BY v.name;
This works as long as vendor names and description names are unique.