Evening. Hope someone can help. Been stumped with this for a few days now...
I have the following table....
| ID | Supplier | Item_1 | Cost_1 | Item_2 | Cost_2 | Item_3 | Cost_3 |
+----+----------+--------+--------+--------+--------+--------+--------+
| 1 | 1 | 732w | 3.99 | 314d | 7.58 | 399p | 15.44 |
| 1 | 2 | SyYh33 | 3.78 | GjuUh4 | 7.60 | 2su7js | 15.45 |
| 1 | 3 | 5443 | 4.01 | 9833 | 7.63 | 7433 | 15.22 |
| 2 | 1 | 596q | 15.42 | 933k | 28.56 | 732c | 69.99 |
| 2 | 2 | hyjs9k | 15.86 | ka7snf | 28.99 | h23nfs | 68.99 |
| 2 | 3 | 5477 | 14.99 | 5658 | 28.49 | 8153 | 70.15 |
+----+----------+--------+--------+--------+--------+--------+--------+
Now what i would like to do is return the cheapest price from columns Cost_1, Cost_2, Cost_3 with it's corresponding Item column and Supplier for each ID....
So basically would like the following result
| ID | Supplier_1 | Item_1 | Cost_1 | Supplier_2 | Item_2 | Cost_2 | Supplier_3 | Item_3 | Cost_3 |
+----+------------+--------+--------+------------+--------+--------+------------+--------+--------+
| 1 | 2 | SyYh33 | 3.78 | 1 | 314d | 7.58 | 3 | 7433 | 15.22 |
| 2 | 3 | 5477 | 14.99 | 3 | 5658 | 28.49 | 2 | h23nfs | 68.99 |
Any pointers would be great. Tried with joins and MIN() but i haven't been able to return the desired results. Hopefully there is a MySQL guru out there that can put me out of my misery. Thanks in advance
Normalize your schema - Otherwise you will have to live with queries like this:
select f.ID,
i1.Supplier as Supplier_1,
i1.Item_1,
i1.Cost_1,
i2.Supplier as Supplier_2,
i2.Item_2,
i2.Cost_2,
i3.Supplier as Supplier_3,
i3.Item_3,
i3.Cost_3
from (select distinct ID from following_table) f
join following_table i1 on i1.ID = f.ID and i1.Supplier = (
select t.Supplier
from following_table t
where t.ID = i1.ID
order by Cost_1 asc
limit 1
)
join following_table i2 on i2.ID = f.ID and i2.Supplier = (
select t.Supplier
from following_table t
where t.ID = i2.ID
order by Cost_2 asc
limit 1
)
join following_table i3 on i3.ID = f.ID and i3.Supplier = (
select t.Supplier
from following_table t
where t.ID = i3.ID
order by Cost_3 asc
limit 1
)
http://sqlfiddle.com/#!9/04933/2
I think what you are looking for is a UNION to combine your results.
SELECT *
FROM your_table
WHERE Cost_1 = (SELECT MIN(Cost_1) FROM your_table)
UNION
SELECT *
FROM your_table
WHERE Cost_2 = (SELECT MIN(Cost_2) FROM your_table)
UNION
SELECT *
FROM your_table
WHERE Cost_3 = (SELECT MIN(Cost_3) FROM your_table)
Related
Sorry for the vague title, but I don't know how to word this type of problem better. Here is a simple example to explain it. I have to tables: OrderItemList and OrderHistoryLog.
OrderItemList:
|------------------------------|
| OrderNo | ItemNo | Loc | Qty |
|------------------------------|
| 100 | A | 1 | 1 |
| 101 | A | 1 | 2 |
| 102 | A | 1 | 1 |
| 103 | A | 2 | 1 |
| 104 | A | 2 | 1 |
OrderHistoryLog:
|------------------------------|
| OrderNo | ItemNo | Loc | Qty |
|------------------------------|
| 50 | A | 1 | 5 |
| 51 | A | 1 | 2 |
| 100 | A | 1 | 1 |
| 102 | A | 1 | 3 |
| 103 | A | 2 | 1 |
I need to show the records in the OrderItemList along with a LocHistQty field, which is the sum(Qty) from the OrderHistoryLog table for a given Item and Location, but only for the orders that are present in the OrderItemList.
For the above example, the result should be:
Result:
|------------------------------------------------------
| OrderNo | ItemNo | Loc | Qty | HistQty | LocHistQty |
|------------------------------|-----------------------
| 100 | A | 1 | 1 | 1 | 4 |
| 101 | A | 1 | 2 | 0 | 4 |
| 102 | A | 1 | 1 | 3 | 4 |
| 103 | A | 2 | 1 | 1 | 1 |
| 104 | A | 2 | 1 | 0 | 1 |
It is the last field, LocHistQty that I could use some help with. Here is what I started with (does not work):
select OI.OrderNo, OI.ItemNo, OI.Loc, OI.Qty, IFNULL(OL.Qty, 0) as HistQty, OL2.LocHistQty
from OrderItemList OI
left join OrderItemLog OL on OL.OrderNo = OI.OrderNo and OL.ItemNo = OI.ItemNo
join
(
select ItemNo, Loc, sum(qty) as LocHistQty
from zOrderItemLog
group by ItemNo, Loc
) as OL2
on OL2.ItemNo = OI.ItemNo and OL2.Loc = OI.Loc
order by OrderNo
The issue is with the above SQL is that LocHistQty contains the summary of the Qty for all orders (=11 for Loc 1 and 1 for Loc 2), not only the ones in OrderItemList.
Lastly, the real data is voluminous and query performance is important.
Help would be much appreciated.
The subquery can join with OrderItemList to restrict the order numbers that it sums.
select OI.OrderNo, OI.ItemNo, OI.Loc, OI.Qty, IFNULL(OL.Qty, 0) as HistQty, OL2.LocHistQty
from OrderItemList OI
left join OrderItemLog OL on OL.OrderNo = OI.OrderNo and OL.ItemNo = OI.ItemNo
join
(
select OL.ItemNo, OL.Loc, sum(OL.qty) as LocHistQty
from OrderItemLog AS OL
JOIN OrderItemList AS OI ON OL.OrderNo = OI.OrderNo
group by OL.ItemNo, OL.Loc
) as OL2
on OL2.ItemNo = OI.ItemNo and OL2.Loc = OI.Loc
order by OrderNo
DEMO
Option 1
SELECT
OrderNo,
ItemNo,
Loc,
Qty,
(SELECT
Qty
FROM
OrderHistoryLog AS A
WHERE
A.OrderNo = B.OrderNo AND A.Loc = B.Loc) AS HistQty,
(SELECT
SUM(Qty)
FROM
OrderHistoryLog AS D
WHERE
D.OrderNo = B.OrderNo AND D.Loc = B.Loc) AS LocHistQty
FROM
OrderItemList AS B;
Option 2
SELECT
B.OrderNo,
B.ItemNo,
B.Loc,
B.Qty,
C.Qty AS HistQty,
(SELECT
SUM(Qty)
FROM
OrderHistoryLog AS A
WHERE
A.OrderNo = B.OrderNo AND A.Loc = B.Loc) AS LocHistQty
FROM
OrderItemList AS B,
OrderHistoryLog AS C
WHERE
C.OrderNo = B.OrderNo AND C.Loc = B.Loc;
I've got these 3 tables:
___Kardex
|--------|---------|-------------|
| KDX_Id | KDX_VIP | KDX_Regular |
|--------|---------|-------------|
| 1 | No | No |
| 2 | No | No |
|--------|---------|-------------|
___BillableDatas
|--------|---------------|
| BIL_Id | BIL_BookingId |
|--------|---------------|
| 1 | 99 |
| 2 | 99 |
| 3 | 100 |
|--------|---------------|
___Bookings
|--------|--------------|
| BOO_Id | BOO_ClientId |
|--------|--------------|
| 99 | 1 |
| 100 | 2 |
|--------|--------------|
I want to loop into ___Kardex and count for each client:
- The number of bookings the client booked (containing in ___Bookings).
- The number of nights the client spent (containing in ___BillableDatas).
So I tried:
SELECT
KDX_Id,
(
SELECT COUNT(BOO_Id)
FROM ___Bookings
WHERE ___Kardex.KDX_Id = ___Bookings.BOO_ClientId
) AS nb_bookings,
(
SELECT COUNT(BIL_Id)
FROM ___BillableDatas
WHERE ___Kardex.KDX_Id = ___Bookings.BOO_ClientId
AND ___Bookings.BOO_Id = ___BillableDatas.BIL_BookingId
) AS nb_bookings
FROM ___Kardex
But I get empty datas.
Could you please help ?
Here the SQLFiddle: http://sqlfiddle.com/#!9/cf1832
The expected result is:
|--------|-------------|-----------|
| KDX_Id | nb_bookings | nb_nights |
|--------|-------------|-----------|
| 1 | 1 | 2 |
| 2 | 1 | 1 |
|--------|-------------|-----------|
Thanks.
Here you go :
SELECT
KDX_Id,
(
SELECT COUNT(BOO_Id)
FROM ___Bookings
WHERE KDX_Id = ___Bookings.BOO_ClientId
) AS nb_bookings,
(
SELECT COUNT(BIL_Id)
FROM ___Bookings, ___BillableDatas
WHERE ___Bookings.BOO_Id = ___BillableDatas.BIL_BookingId
AND KDX_Id = ___Bookings.BOO_ClientId
) AS nb_nights
FROM ___Kardex
I have two tables (PO and GRN).
I want to get:
[This is what I am doing:][1] http://sqlfiddle.com/#!9/db000/2
I get these results (wrong po_qty , GRN_qty and GRN_balance ).
What I am expecting is:
| Item | PONO | po_qty | GRN_qty | GRN_balance |
|------|------|--------|---------|-------------|
| A | po1 | 70 | 65 | 5 |
| B | po1 | 50 | 0 | 50 |
| C | po2 | 10 | 5 | 5 |
| D | po3 | 20 | 0 | 20 |
| A | po4 | 15 | 10 | 5 |
Here is a way of doing it
select
p.Item,
p.PONO,
sum(p.Qty) as po_qty,
coalesce(g.GRN_qty,0) ,
sum(p.Qty) - coalesce(g.GRN_qty,0) as GRN_balance
from PO p
left join (
select PONO,Item,sum(Qty) as GRN_qty from GRN
group by PONO,Item
)g
on g.PONO = p.PONO and g.Item = p.Item
group by p.Item,p.PONO
order by p.PONO
http://sqlfiddle.com/#!9/db000/30
I modified your SQL. Please execute and see
SELECT PO.Item,PO.PONO,
PO.Qty as po_qty,
GRN.Qty as GRN_qty,
PO.Qty- GRN.Qty as GRN_balance
from PO,GRN
group by PO.Item
Thank you..
How to pair rows with imperfecty in mysql? Imperfect, meaning the rows are not exactly paired as in and out. Sometimes, there are two in with one out or no out at all or two or more out with one in or no in at all.
The table look like this:
| id | action | date |
+----+--------+---------------------+
| 1 | in | 19.1.2012 15:41:52 |
| 1 | out | 19.1.2012 15:55:52 |
| 2 | in | 19.2.2012 15:55:52 |
| 2 | out | 19.2.2012 17:55:53 |
| 1 | in | 19.3.2012 15:55:54 |
| 1 | in | 19.3.2012 17:55:55 |
| 1 | out | 19.3.2012 19:55:56 |
| 3 | in | 19.4.2012 15:55:57 |
| 3 | out | 19.4.2012 17:55:58 |
| 3 | out | 19.4.2012 19:55:59 |
+----+--------+---------------------+
The desired result is like this:
+----+--------+---------------------+
| id | action | date |
+----+--------+---------------------+
| 1 | in | 19.1.2012 15:41:52 |
| 1 | out | 19.1.2012 15:55:52 |
| 2 | in | 19.2.2012 15:55:52 |
| 2 | out | 19.2.2012 17:55:53 |
| 1 | in | 19.3.2012 17:55:55 |
| 1 | out | 19.3.2012 19:55:56 |
| 3 | in | 19.4.2012 15:55:57 |
| 3 | out | 19.4.2012 17:55:58 |
+----+--------+---------------------+
This is the best desireed result
+----+---------------------+---------------------+
| id | date_in | date_out |
+----+---------------------+---------------------+
| 1 | 19.1.2012 15:41:52 | 19.1.2012 15:55:52 |
| 2 | 19.2.2012 15:55:52 | 19.2.2012 17:55:53 |
| 1 | 19.3.2012 17:55:55 | 19.3.2012 19:55:56 |
| 3 | 19.4.2012 15:55:57 | 19.4.2012 17:55:58 |
+----+---------------------+---------------------+
Here is a code, but it yields different result, can anyone figure out where the error is?
enter code here SELECT c.e_id
, CAST(c.in_time AS DATETIME) AS in_time
, c.out_time
FROM (
SELECT IF(#prev_id = d.id,#in_time,#in_time:=NULL) AS reset_in_time
, #in_time := IF(d.action = 'in',d.date,#in_time) AS in_time
, IF(d.action = 'out',d.date,NULL) AS out_time
, #prev_id := d.id AS id
FROM (
SELECT id, date_, action
FROM e
JOIN (SELECT #prev_id := NULL, #in_time := NULL) f
ORDER BY id, date, action
) d
) c
WHERE c.out_time IS NOT NULL
ORDER BY c.out_time enter code here
This selects an in event into a, an out event into b and uses a LEFT JOIN to eliminate the row if there exists an event c for the same id between them; that will simply get all in/out times that don't have an extra in or out between them.
SELECT a.id, a.date date_in, b.date date_out
FROM mytable a
JOIN mytable b
ON a.id = b.id AND a.date < b.date
LEFT JOIN mytable c
ON a.id = c.id AND c.date < b.date AND c.date > a.date
WHERE a.action = 'in' AND b.action = 'out' AND c.action IS NULL
ORDER BY a.date;
An SQLfiddle to test with.
I have two tables like this
profile_answers
+---------+------------+
| id | class_name |
+---------+------------+
| 1 | Class 1 |
| 2 | Class 2 |
| 3 | Class 1 |
+---------+------------+
educations
+---------+--------------------+------------+
| id | profile_answers_id | sample |
+---------+--------------------+------------+
| 1 | 1 | 1234 |
| 2 | 1 | 2334 |
| 3 | 1 | 3434 |
+---------+------------+--------------------+
I ran the query,
select educations.profile_answer_id, GROUP_CONCAT(educations.sample) from educations
LEFT JOIN profile_answers ON educations.profile_answers_id = profile_answers.id
I got
+--------+--------------------+-------------+
| id | sample |
+---------+--------------------+------------+
| 1 | 1234,2334,3434 |
+---------+------------+--------------------+
I actually want,
+--------+--------------------+-------------+
| id | sample |
+---------+--------------------+------------+
| 1 | 1234,2334,3434 |
| 2 | NULL |
| 3 | NULL |
+---------+------------+--------------------+
SELECT id,IFNULL(samples,'NULL') sample FROM
(
SELECT
AA.id,
GROUP_CONCAT(DISTINCT BB.sample) samples
FROM
profile_answers AA LEFT JOIN educations BB
ON AA.id = BB.profile_answers_id
GROUP BY AA.id
) A;
Looks like you're missing your GROUP BY:
select profile_answers.id, GROUP_CONCAT(educations.sample)
from profile_answers
LEFT JOIN educations ON educations.profile_answers_id = profile_answers.id
GROUP BY profile_answers.id
I also altered your JOIN to make the profile_answers table your main table.
Good luck.