I have 3 tables.
A table:
id_a | description
-------------------
1 | X
2 | Y
3 | Z
4 | H
B table:
id_b | description
-------------------
1 | J
2 | K
3 | W
C table:
id_c | idex_a | idex_b | quantity
----------------------------------
1 | 1 | 1 | 10
2 | 1 | 2 | 32
3 | 2 | 3 | 41
4 | 1 | 3 | 10
5 | 3 | 2 | 24
6 | 3 | 3 | 26
How can I obtain this result?
A.id_a | A.description | All B.description, B.quantity IN C WHITH A.id_a = C.idex_a
1 | X | J[10], K[32], W[10]
2 | Y | W[41]
3 | Z | K[24], W[26]
4 | H |
You can try the following:
select a.id_a
, a.description
, coalesce( group_concat(distinct concat(b.description, '[', c.quantity, ']') order by b.id_b separator ', ')
, '')
from a
left join c on a.id_a = c.idex_a
left join b on b.id_b = c.idex_b
group by a.id_a
, a.description
SQLFiddle
Related
I'm struggling describing the problem in the Title, let alone looking for a solution that may well exist, so please excuse, or point me to the thread. I need to pad rows, so I have 4 rows per Category as in the simplified scenario below:
mysql> select * from a;
+-------+
| Num |
+-------+
| 1 |
| 2 |
| 3 |
| 4 |
+-------+
mysql> select * from b;
+----------+------+------+
| Category | Num | Data |
+----------+------+------+
| X | 2 | 10 |
| X | 3 | 12 |
| X | 4 | 8 |
| Y | 1 | 0 |
| Y | 2 | 19 |
| y | 3 | 15 |
| y | 4 | 22 |
| Z | 2 | 10 |
+----------+------+------+
The result I need is always 4 rows per category (table b will always ever have one of Num = 1, 2, 3 or 4 per category), set data = null for the padded rows:
mysql> select * from c;
+----------+------+------+
| Category | Num | Data |
+----------+------+------+
| X | 1 | NULL |
| X | 2 | 10 |
| X | 3 | 12 |
| X | 4 | 8 |
| Y | 1 | 0 |
| Y | 2 | 19 |
| y | 3 | 15 |
| y | 4 | 22 |
| Z | 1 | NULL |
| Z | 2 | 10 |
| Z | 3 | NULL |
| Z | 4 | NULL |
+----------+------+------+
I created table a artificially, as I thought it may help with the (INSERT) query?!
You can cross join table a with all available categories in table b, and then bring table b with a left join.
select
c.category,
a.num,
b.data
from a
cross join (select distinct category from b) c
left join b on b.category = c.category and b.num = a.num
You can easily turn this to an insert query to another table:
insert into c(category, num, data)
select
c.category,
a.num,
b.data
from a
cross join (select distinct category from b) c
left join b on b.category = c.category and b.num = a.num
You need left join
select a.num, b.category , b.data
from tablea a
left join tableb b on a.num = b.num
and for insert
insert into tablec (num, category, data)
select a.num, b.category , b.data
from tablea a
left join tableb b on a.num = b.num
of if need an update for the exing rows
update tablec c
inner join (
select a.num, b.category , ifnull(b.data,0)
from tablea a
left join tableb b on a.num = b.num ) t t.num= c.num and t.category = c.category
set data = t.data
I have a table named Story:
sID | sName | sView
1 | s1 | 1
2 | s2 | 11
3 | s3 | 142
4 | s4 | 152
Table Chapter:
chID | sID | chName | chContent
1 | 1 | ch1 | aaa
2 | 2 | ch2 | aaa
3 | 3 | ch3 | aaa
4 | 1 | ch4 | aaa
5 | 3 | ch5 | aaa
6 | 1 | ch6 | aaa
7 | 2 | ch7 | aaa
NaviteQuery:
SELECT s.*, MAX(c.chID) as chapterID FROM Story s
LEFT JOIN Chapter c ON s.sID = c.sID
GROUP BY s.sID
Result:
sID | sName | sView | chapterID
1 | s1 | 1 | 6
2 | s2 | 11 | 7
3 | s3 | 142 | 5
4 | s4 | 152 | null
But you should get a 'SELECT s. *, c. * FROM ....', who can help me with !!!!
You can write it on some differents way. For example you can use it:
SELECT s.*, c.* FROM Story s
LEFT JOIN (SELECT * FROM Chapter c INNER JOIN (SELECT MAX(c.chID) as chapterID FROM Story s
LEFT JOIN Chapter c ON s.sID = c.sID
GROUP BY s.sID) d ON c.chID = d.chapterID) c ON s.sID = c.sID
I'm banging my head with some SQL query and pretty much the logic behind it.
Let's assume we have these tables:
Table hotels
+----+---------+
| id | name |
+----+---------+
| 1 | Hotel A |
+----+---------+
Table hotel_rooms
+----+----------+-----------+
| id | hotel_id | room_type |
+----+----------+-----------+
| 1 | 1 | dbl | <- can be used as A,B,C,D,E,F
| 2 | 1 | dbl | <- can be used as B,C,D,E,F
| 3 | 1 | sng | <- can be used as A
| 4 | 1 | trp | <- can be used as D,E,F
+----+----------+-----------+
Table hotel_room_usages
+----+---------+-------+
| id | room_id | usage |
+----+---------+-------+
| 1 | 1 | B |
| 2 | 1 | C |
| 3 | 1 | A |
| 4 | 1 | D |
| 5 | 1 | E |
| 6 | 1 | F |
| 7 | 2 | B |
| 8 | 2 | C |
| 9 | 2 | D |
| 10 | 2 | E |
| 11 | 2 | F |
| 12 | 3 | A |
| 13 | 4 | D |
| 14 | 4 | E |
| 15 | 4 | F |
+----+---------+-------+
If I search for 2 rooms with usage A or 3 rooms with usage D as separate queries the result should be Hotel A with the corresponding IDs of the rooms.
The problem is if I search for 2 rooms with usage A and 3 rooms with usage D at the same time it returns also the hotel A because it doesn't count that some rooms can be used as A and D.
The rooms should be unique /total of 5/. The current example should not return a result because there are total of 4 rooms in the hotel.
does this help?
-- two rooms with usage a
select id from hotel_room_usages where usage = 'a'
-- three rooms with usage d
select id from hotel_room_usages where usage = 'd'
-- count of rooms with either
select count(distinct(room_id)) from hotel_room_usages where usage in ('a','d')
SELECT h.name AS hotel_name
, q.*
FROM
(
SELECT r.hotel_id
, COUNT(DISTINCT CASE WHEN ruA.room_id IS NOT NULL AND ruD.room_id IS NULL THEN ruA.room_id END) AS TotalRoomsOnlyA
, COUNT(DISTINCT CASE WHEN ruD.room_id IS NOT NULL AND ruA.room_id IS NULL THEN ruD.room_id END) AS TotalRoomsOnlyD
, COUNT(DISTINCT CASE WHEN ruA.room_id IS NOT NULL AND ruD.room_id IS NOT NULL THEN r.id END) AS TotalRoomsAandD
, COUNT(DISTINCT r.id) AS TotalRoomsAorD
FROM hotel_rooms AS r
LEFT JOIN hotel_room_usages AS ruA ON (ruA.room_id = r.id AND ruA.usage = 'A')
LEFT JOIN hotel_room_usages AS ruD ON (ruD.room_id = r.id AND ruD.usage = 'D')
WHERE (ruA.room_id IS NOT NULL OR ruD.room_id IS NOT NULL)
GROUP BY r.hotel_id
) q
JOIN hotels AS h ON (h.id = q.hotel_id)
CROSS JOIN (SELECT 2 AS a, 3 AS d) AS n
WHERE TotalRoomsAorD >= (a+d)
AND (
((TotalRoomsOnlyA + TotalRoomsAandD) >= a AND TotalRoomsOnlyD >= d) OR
(TotalRoomsOnlyA >= d AND (TotalRoomsOnlyD + TotalRoomsAandD) >= d) OR
((TotalRoomsOnlyA + TotalRoomsAandD/2) >= a AND (TotalRoomsOnlyD + TotalRoomsAandD/2) >= d)
)
ORDER BY h.name;
Test on db<>fiddle here
I try to use LEFT JOIN but I dont get the result I want.
I have 2 tables
Table 1:
Persons
UID | Names | GID
1 | Mike | 1
2 | Tom | 1
3 | Brenda | 1
4 | Sophie | 2
Table 2:
DailyLog
ID | UID | GID | DATE
1 | 1 | 1 | 2017-10-13
2 | 2 | 1 | 2017-10-13
3 | 3 | 1 | 2017-10-13
4 | 1 | 1 | 2017-10-13
5 | 2 | 1 | 2017-10-14
6 | 1 | 1 | 2017-10-14
7 | 1 | 1 | 2017-10-15
I want search a name who is not have a stamp date of today (2017-10-15) in GID 1,
a result like this:
UID | Name
2 | Tom
3 | Brenda
I use SQL Left Join, but the result not what I expected.
SELECT DISTINCT a.uid
, a.Name
, b.date
FROM Persons AS a
LEFT
JOIN dailylog AS b
ON a.uid = b.uid
AND a.gid = b.gid
WHERE (b.date IS NULL OR b.date !='2017-10-15' )
AND a.gid='1'
Thank you
you could use a not In clause
SELECT a.uid
, a.Name
, b.date
FROM Persons
where uid not in (
select uid from DailyLog
where GID = 1
and DATE = '2017-10-15'
)
I am looking to get all values from first table along with joinned values from second table.
Table 1 is fee_category with fields:
id | Category
1 | A
2 | B
3 | C
4 | D
Table 2 is fee_charge with fields:
id | std_id | particularID | CategoryID | assign | amount
1 | 1 | 1 | 1 | 0 | 1000
2 | 1 | 1 | 2 | 1 | 12000
3 | 1 | 2 | 3 | 0 | 3000
4 | 1 | 2 | 4 | 0 | 10
5 | 2 | 1 | 2 | 0 | 100
6 | 2 | 2 | 3 | 0 | 120
Base table is "fee_category" from which I need all values left joining with "fee_charge" from where I need values or NULL for a particular std_id and particularID
SELECT fee_category.id, fee_category.Category, fee_charge.std_id
, fee_charge.particularID, fee_charge.CategoryID, fee_charge.assign, fee_charge.amount FROM fee_category
LEFT join fee_charge on fee_category.id=fee_charge.CategoryID
where (fee_charge.std_id = 1 OR fee_charge.std_id IS NULL)
AND (fee_charge.particularID = 1 OR fee_charge.particularID IS NULL)
group By fee_category.id
order By fee_charge.assign DESC
Here I am trying to get all categories of std_id=1 and particularID=1
Correct result should be
id | Category | std_id | particularID | CategoryID | assign | amount
1 | A | 1 | 1 | 1 | 0 | 1000
1 | B | 1 | 1 | 2 | 1 | 12000
1 | C | 1 | NULL | NULL | NULL | NULL
1 | D | 1 | NULL | NULL | NULL | NULL
I am trying various versions of the above query but not getting proper result. Please help
SELECT fee_category.id
, fee_category.Category
, X.std_id
, X.particularID
, X.CategoryID
, X.assign
, X.amount
FROM fee_category
LEFT JOIN
(SELECT * FROM fee_charge
WHERE fee_charge.std_id = 1
AND fee_charge.particularID = 1) AS X
ON x.CategoryID = fee_category.id
It's very hard to follow when the fiddle doesn't match the question, so I may have misunderstood, but perhaps you're after something like this...
SELECT x.id
, z.category
, x.std_id
, y.particularID
, y.categoryID
, y.assign
, y.amount
FROM fee_charge x
LEFT
JOIN fee_charge y
ON y.id = x.id
AND y.particularID = 1
JOIN fee_category z
ON z.id = x.categoryID
WHERE x.std_id = 1;