Need result for the MySQL joins for this method - mysql

I have two table one is order_details and second is orders.
1) order_details
id | order_id | item | order_units | is_cancelled |
------------------------------------------------------------------
1 | 00001 | Mobile | 2 | 0 |
2 | 00001 | Headphone | 2 | 0 |
3 | 00001 | cover | 5 | 0 |
4 | 00002 | charger | 1 | 0 |
5 | 00002 | mobile | 1 | 0 |
6 | 00004 | Tablet | 2 | 0 |
7 | 00005 | Mobile | 1 | 0 |
8 | 00005 | Battery | 2 | 1 |
9 | 00006 | Mobile | 1 | 0 |
10 | 00006 | speaker | 1 | 0 |
11 | 00006 | Motinor | 1 | 0 |
12 | 00007 | Laptop | 2 | 0 |
2) orders
order_id | date | time |total_amount| round |discount|refund
-----------------------------------------------------------------------
00001 | 2017-06-16 |10:10:45 | 456.12 |-0.12 | 0 | 0
00002 | 2017-06-16 |10:25:45 | 600.00 | 0.00 | 10 | 50
00004 | 2017-06-16 |11:10:45 | 300.55 |-0.05 | 0 | 0
00005 | 2017-06-16 |12:10:45 | 200.45 | 0.05 | 20 | 0
00006 | 2017-06-16 |12:40:45 | 685.00 | 0.00 | 50 | 0
00007 | 2017-06-24 |14:10:45 | 888.35 | 0.15 | 0 | 0
I want to join the "order_details" with "orders" and the result should be as below:
---------------------------------------------------------------------
date | time | hour |order_count| total_units| net_amount
---------------------------------------------------------------------
| 2017-06-16 |10:10:45 | 10 | 2 | 11 | 996
| 2017-06-16 |11:10:45 | 11 | 1 | 2 | 300.50
| 2017-06-16 |12:40:45 | 12 | 2 | 4 | 180.50
--------------------------------------------------------------------
I have created a sql query for the above result format and all columns outputs are correct except the "total_units", its showing null.
The following query i have used:
SELECT hdr.date,hdr.time, LPAD(HOUR(hdr.time),2,'0') AS hour, COUNT(hdr.`order_id`) AS order_count, dtl.total_units, SUM((hdr.total_amount+hdr.round-hdr.discount)-hdr.refund) AS net_amount
FROM orders hdr
LEFT JOIN (
SELECT order_id, SUM(qty) AS total_units
FROM order_details
WHERE is_cancelled=0) dtl ON dtl.order_id = hdr.order_id
WHERE DATE(hdr.date) = '2017-06-16 ' AND (HOUR(hdr.time) BETWEEN ('10') AND ('12'))
GROUP BY hdr.date, HOUR(hdr.time)
Please help me to correct this query and generate the exact output as above.

Sorry, One correction in my query..
SELECT hdr.date,hdr.time, LPAD(HOUR(hdr.time),2,'0') AS hour, COUNT(hdr.`order_id`) AS order_count, dtl.total_units, SUM((hdr.total_amount+hdr.round-hdr.discount)-hdr.refund) AS net_amount
FROM orders hdr
LEFT JOIN (
SELECT order_id, SUM(order_units) AS total_units
FROM order_details
WHERE is_cancelled=0) dtl ON dtl.order_id = hdr.order_id
WHERE DATE(hdr.date) = '2017-06-16 ' AND (HOUR(hdr.time) BETWEEN ('10') AND ('12'))
GROUP BY hdr.date, HOUR(hdr.time)

I have made some corrections in the query and it is working fine now:
SELECT hdr.date,hdr.time, LPAD(HOUR(hdr.time),2,'0') AS hour, COUNT(hdr.`order_id`) AS order_count, SUM(dtl.order_units) AS total_units, SUM((hdr.total_amount+hdr.round-hdr.discount)-hdr.refund) AS net_amount
FROM orders hdr
LEFT JOIN (
SELECT order_id, SUM(order_units) AS order_units
FROM order_details
WHERE is_cancelled=0 GROUP BY order_id) dtl ON dtl.order_id = hdr.order_id
WHERE DATE(hdr.date) = '2017-06-16 ' AND (HOUR(hdr.time) BETWEEN ('10') AND ('12'))
GROUP BY hdr.date, HOUR(hdr.time)
Thank you.

Related

How to write mysql innerquery when get the records count from same table

Query to get results from 2 tables:
SELECT path.* FROM (SELECT tbc.course_name
slp.course_id,slp.student_type,slp.stu_reference_id,
count(slp.course_id) as counttotalWatchedStudents
from tbl_student_learning_path slp LEFT JOIN tbl_courses tbc
on tbc.course_pid = slp.course_id WHERE slp.stu_reference_id =34
and slp.student_type='institute' GROUP BY slp.course_id ) as path
Query result table:
| course_id | totalCollegeStudents | fullwatchedStudentsCount | counttotalWatchedStudents | sumOfWatchPointsForWatchedStudents | totalStudentsAvg | fullwatchedAvg |
|-------------------------------|----------------------|--------------------------|---------------------------|------------------------------------|------------------|----------------|
| Number Systems | 9 | 0 | 3 | 60 | 20.0000 | 0 |
| Percentages | 9 | 0 | 3 | 30 | 10.0000 | 0 |
| Blood Relations | 9 | 3 | 3 | 300 | 100.0000 | 300 |
| Calandar | 9 | 3 | 3 | 300 | 100.0000 | 300 |
| Percentages | 9 | 3 | 3 | 300 | 100.0000 | 300 |
| Permutation & Combination | 9 | 3 | 3 | 300 | 100.0000 | 300 |
| Probability | 9 | 0 | 3 | 90 | 30.0000 | 0 |
| Ratios | 9 | 0 | 3 | 120 | 40.0000 | 0 |
| Time and Work | 9 | 0 | 3 | 150 | 50.0000 | 0 |
| Time Speed & Distance | 9 | 1 | 3 | 140 | 46.6667 | 100 |
| Averages | 9 | 3 | 3 | 300 | 100.0000 | 300 |
| Coding and Decoding | 9 | 3 | 3 | 300 | 100.0000 | 300 |
From the above table, i want to add inner query to the main query
query should be something like this:
( select count(t1.watched_percentage) from tbl_student_learning_path t1
WHERE t1.stu_reference_id =34 and t1.student_type='institute'
AND t1.watched_percentage >= 90 group by t1.course_id )
fullwatchedStudentsCount,
And the result should come like this(this is nothing but if first table counttotalWatchedStudents value is 3 it means that there are 2 type of people
1.students watched full (watched_percentage>=90)
2.students still watching (watched_percentage 1-89)
)
| fullwatchedStudentsCount | fullwatchedStudentsSum |
|--------------------------|------------------------|
| 2 | 200 |
| 1 | 100 |
| 0 | 0 |
| 2 | 200 |
| 1 | 100 |
| 1 | 100 |
| 0 | 0 |
| 2 | 200 |
| 2 | 200 |
| 1 | 100 |
| 2 | 200 |
| 1 | 100 |
If I understand correctly you want sum up the students which saw more than 90% in another column:
I'd do it like this:
SELECT tbc.course_name,
slp.course_id,
slp.student_type,
slp.stu_reference_id,
count(slp.course_id) AS counttotalWatchedStudents,
sum(if(slp.watched_percentage>=90, 1, 0)) AS fullwatchedStudentsCount
sum(if(slp.watched_percentage>=90, watched_percentage, 0)) AS fullwatchedStudentsSum
FROM tbl_student_learning_path slp
LEFT JOIN tbl_courses tbc ON tbc.course_pid = slp.course_id
WHERE slp.stu_reference_id =34
AND slp.student_type='institute'
GROUP BY slp.course_id
enter code here
Hope this helps
So you want to count students with a watched_percentage >= 90? Use conditional aggregation for this:
SELECT
tbc.course_name,
slp.course_id,
slp.student_type,
slp.stu_reference_id,
COUNT(*) as counttotalWatchedStudents,
SUM(slp.watched_percentage >= 90) as fullwatchedStudentsCount,
SUM(slp.watched_percentage < 90) as stillwatchedStudentsCount
FROM tbl_student_learning_path slp
LEFT JOIN tbl_courses tbc ON tbc.course_pid = slp.course_id
WHERE slp.stu_reference_id = 34
AND slp.student_type= 'institute'
GROUP BY slp.course_id;
MySQL treats true = 1 and false = 0, so you can simply sum the trues :-)

Products' quantity calculation based on transactions stored in two different tables

I have three tables:
ITEMS
+----+--------------------------+----------+
| id | nome | quantity |
+----+--------------------------+----------+
| 1 | Pantaloni beige | 10 |
| 2 | Camicia cotone e seta | 1 |
| 3 | Camicia da notte | 5 |
| 4 | Completo notte | 3 |
+----+--------------------------+----------+
TRANSACTIONS
+----+---------------------+----------+-------------+
| id | data | quantity | id_articolo |
+----+---------------------+----------+-------------+
| 1 | 2016-07-19 15:28:09 | 3 | 1 |
| 2 | 2016-07-19 15:29:50 | 1 | 1 |
| 3 | 2016-07-19 15:59:34 | 1 | 2 |
| 4 | 2016-07-19 16:00:59 | 1 | 3 |
| 5 | 2016-07-19 16:01:10 | 1 | 188 |
| 6 | 2016-07-19 16:11:15 | 1 | 193 |
| 7 | 2016-07-19 16:11:24 | 1 | 194 |
| 8 | 2016-07-19 16:11:55 | 1 | 195 |
| 9 | 2016-07-19 16:51:14 | 1 | 204 |
+----+---------------------+----------+-------------+
RETURNED_ITEMS
+----+---------+-------------+----------+
| id | id_reso | id_articolo | quantity |
+----+---------+-------------+----------+
| 1 | 54 | 1 | 6 |
| 2 | 54 | 3 | 1 |
| 3 | 54 | 392 | 1 |
| 4 | 54 | 398 | 1 |
+----+---------+-------------+----------+
joined on "transactions.id_articolo" = "returned_items.id_articolo" = "items.id"
I want to retrieve a complete list containing only available products in which
(items.quantity) - (transactions.quantity) - (returned_items.quantity) > 0
eg. In the data above
item 1 = 0 [excluded]
item 2 = 0 [excluded]
item 3 = 3 [included in the list]
item 4 = 3 [included]
Any idea?
Thanks a lot!
V.
Looks like you will need to use inline views to aggregate quantity from the transactions table and the returned items tables
SELECT i.id
, i.quantity
, IFNULL(t.quantity,0) AS t_quantity
, IFNULL(r.quantity,0) AS r_quantity
, i.quantity - IFNULL(t.quantity,0) + IFNULL(r.quantity,0) AS calc_qty
FROM items i
LEFT
JOIN ( SELECT tt.id_articolo
, SUM(tt.quantity) AS quantity
FROM transactions tt
GROUP BY tt.id_articolo
) t
ON t.id_articolo = i.id
LEFT
JOIN ( SELECT rr.id_articolo
, SUM(rr.quantity) AS quantity
FROM returned_items rr
GROUP BY rr.id_articolo
) r
ON r.id_articolo = i.id
HAVING calc_qty > 0
ORDER BY i.id
For testing, omit the HAVING clause.
Note that the expression for calc_qty in the query above includes an addition operation. Go ahead and combine the quantity values with whatever arithmetic operations you need. Go ahead and do a subtraction is that satisfies the requirements.

How can I order a table from another table's column then run a query?

I'm building a website for our ball team for the fun of it and keeping track of stats using PHP and SQL for the database. I've learned both by reading the manuals and through forums. I'm working on building a query that will display the current longest hitting streak. I stumbled across a page about detecting runs and streaks and am trying to work with that. I'm really new to all this stuff, so maybe I've structured my tables incorrectly.
Table "games"
+--------+------------+------+
| GameID | Date | Time |
+--------+------------+------+
| 1 | 2015/08/19 | 6:30 |
| 2 | 2015/08/20 | 6:30 |
| 3 | 2015/08/22 | 6:30 |
| 4 | 2015/08/24 | 8:00 |
| 5 | 2015/08/24 | 6:30 |
| 6 | 2015/07/15 | 8:00 |
+--------+------------+------+
Table "player"
+--------+----+---+
| GameID | AB | H |
+--------+----+---+
| 1 | 3 | 1 |
| 2 | 4 | 2 |
| 3 | 2 | 0 |
| 4 | 3 | 0 |
| 5 | 2 | 1 |
| 6 | 3 | 0 |
+--------+----+---+
Code
SELECT games.GameID, GR.H,
(SELECT COUNT(*)
FROM player G
WHERE (CASE WHEN G.H > 0 THEN 1 ELSE 0 END) <> (CASE WHEN GR.H > 0 THEN 1 ELSE 0 END)
AND G.GameID <= GR.GameID) as RunGroup
FROM player GR
INNER JOIN games
ON GR.gameID = games.GameID
ORDER BY Date ASC, Time ASC
Basically in order to correctly get the hit streak right, I need to reorder the GameIDs on the "player" table based on the Date (ASC) and Time (ASC) on the "games" table before executing the RunGroup part of the code. Obviously by adding the ORDER BY, everything gets sorted only after the RunGroup has finished querying and results in incorrect data. I've been stuck here for a few days and now need some help.
The Result I currently get is:
+--------+---+----------+
| GameID | H | RunGroup |
+--------+---+----------+
| 6 | 0 | 3 |
| 1 | 1 | 0 |
| 2 | 2 | 0 |
| 3 | 0 | 2 |
| 5 | 1 | 2 |
| 4 | 0 | 2 |
+--------+---+----------+
This is what I'm trying to achieve:
+--------+---+----------+
| GameID | H | RunGroup |
+--------+---+----------+
| 6 | 0 | 0 |
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 0 | 2 |
| 5 | 1 | 2 |
| 4 | 0 | 3 |
+--------+---+----------+
Thanks
Consider the following:
DROP TABLE IF EXISTS games;
CREATE TABLE games
(game_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,date_played DATETIME NOT NULL
);
INSERT INTO games VALUES
(1,'2015/08/19 18:30:00'),
(2,'2015/08/20 18:30:00'),
(3,'2015/08/22 18:30:00'),
(4,'2015/08/24 20:00:00'),
(5,'2015/08/24 18:30:00'),
(6,'2015/07/15 20:00:00');
DROP TABLE IF EXISTS stats;
CREATE TABLE stats
(player_id INT NOT NULL
,game_id INT NOT NULL
,at_bat INT NOT NULL
,hits INT NOT NULL
,PRIMARY KEY(player_id,game_id)
);
INSERT INTO stats VALUES
(1,1,3,1),
(1,2,4,2),
(1,3,2,0),
(1,4,3,0),
(1,5,2,1),
(1,6,3,0),
(2,1,2,1),
(2,2,3,2),
(2,3,3,0),
(2,4,3,1),
(2,5,2,1),
(2,6,3,0);
SELECT x.*
, SUM(y.at_bat) runningAB
, SUM(y.hits) runningH
, SUM(y.hits)/SUM(y.at_bat) BA
FROM
(
SELECT s.*, g.date_played FROM stats s JOIN games g ON g.game_id = s.game_id
) x
JOIN
(
SELECT s.*, g.date_played FROM stats s JOIN games g ON g.game_id = s.game_id
) y
ON y.player_id = x.player_id
AND y.date_played <= x.date_played
GROUP
BY x.player_id
, x.date_played;
+-----------+---------+--------+------+---------------------+-----------+----------+--------+
| player_id | game_id | at_bat | hits | date_played | runningAB | runningH | BA |
+-----------+---------+--------+------+---------------------+-----------+----------+--------+
| 1 | 6 | 3 | 0 | 2015-07-15 20:00:00 | 3 | 0 | 0.0000 |
| 1 | 1 | 3 | 1 | 2015-08-19 18:30:00 | 6 | 1 | 0.1667 |
| 1 | 2 | 4 | 2 | 2015-08-20 18:30:00 | 10 | 3 | 0.3000 |
| 1 | 3 | 2 | 0 | 2015-08-22 18:30:00 | 12 | 3 | 0.2500 |
| 1 | 5 | 2 | 1 | 2015-08-24 18:30:00 | 14 | 4 | 0.2857 |
| 1 | 4 | 3 | 0 | 2015-08-24 20:00:00 | 17 | 4 | 0.2353 |
| 2 | 6 | 3 | 0 | 2015-07-15 20:00:00 | 3 | 0 | 0.0000 |
| 2 | 1 | 2 | 1 | 2015-08-19 18:30:00 | 5 | 1 | 0.2000 |
| 2 | 2 | 3 | 2 | 2015-08-20 18:30:00 | 8 | 3 | 0.3750 |
| 2 | 3 | 3 | 0 | 2015-08-22 18:30:00 | 11 | 3 | 0.2727 |
| 2 | 5 | 2 | 1 | 2015-08-24 18:30:00 | 13 | 4 | 0.3077 |
| 2 | 4 | 3 | 1 | 2015-08-24 20:00:00 | 16 | 5 | 0.3125 |
+-----------+---------+--------+------+---------------------+-----------+----------+--------+
I rebuilt my database to have only one table to contain the stats from all players. From there i was able to use this query to find my longest current hitting streak for a certain player.
SELECT *
FROM (SELECT (CASE WHEN h > 0 THEN 1 ELSE 0 END) As H, MIN(date_played) as StartDate,
MAX(date_played) as EndDate, COUNT(*) as Games
FROM (SELECT date_played, (CASE WHEN h > 0 THEN 1 ELSE 0 END) as H, (SELECT COUNT(*)
FROM stats G WHERE ((CASE WHEN G.h > 0 THEN 1 ELSE 0 END) <> (CASE WHEN GR.h > 0 THEN 1 ELSE 0 END))
AND G.date_played <= GR.date_played AND player_id = 13) as RunGroup
FROM stats GR
WHERE player_id = 13) A
GROUP BY H, RunGroup
ORDER BY Min(date_played)) A
WHERE H = 1
ORDER BY Games DESC
LIMIT 1

Order by and group by

I am trying to show delivery charges for a shop I am building, there are three tables in the database 1 for the service ie Royal Mail, Carrier..., one for the band ie. UK, Europe, Worldwide1 etc.. and one for the charges (qty = weight)
I have a database of three tables that, when joined form the following
+------------------+-----+-----------+-------+---------+---------------+----------+-------+-------------+
| name | qty | serviceID | basis | bandID | initial_charge | chargeID | price | total_price |
+------------------+-----+-----------+-------+---------+---------------+----------+-------+-------------+
| Collect in store | 0 | 3 | | 1 | 3 | 0.00 | 2 | 0.00 |
| Royal mail | 0 | 1 | 2 | 4 | 2.00 | 3 | 0.00 | 2.00 |
| Royal mail | 1 | 1 | 2 | 4 | 2.00 | 4 | 1.00 | 3.00 |
| APC | 0 | 2 | 1 | 1 | 0.00 | 6 | 5.95 | 5.95 |
+------------------+-----+-----------+-------+---------+---------------+----------+-------+-------------+
Basically what I want to do is (as you can see) Royal Mail has two entries as there are more than one entry in the joined table. What I would like to do is show the highest of the two royal mail entries (I was initially trying to group by service_id) whilst also maintaining the two other services with different service id's
Any assistance would be great as this is driving me mad. I feel like I have tried every combination going!
In the example below the qty (weight) of the items is 3kg
SELECT
`service`.`name`,
`charge`.`qty`,
`service`.`serviceID`,
`band`.`bandID`,
`band`.`initial_charge`,
`charge`.`chargeID`,
`charge`.`price`,
`band`.`initial_charge` + `charge`.`price` AS `total_price`
FROM
`delivery_band` AS `band`
LEFT JOIN
`delivery_charge` AS `charge`
ON
`charge`.`bandID` = `band`.`bandID`
AND
`charge`.`qty` < '3'
LEFT JOIN
`delivery_service` AS `service`
ON
`service`.`serviceID` = `band`.`serviceID`
WHERE
FIND_IN_SET( '225', `band`.`accepted_countries` )
AND
(
`band`.`min_qty` >= '3'
OR
`band`.`min_qty` = '0'
)
AND
(
`band`.`max_qty` <= '3'
OR
`band`.`max_qty` = '0'
)
delivery_service
+-----------+------------------+
| serviceID | name |
+-----------+------------------+
| 1 | Royal mail |
| 2 | APC |
| 3 | Collect in store |
+-----------+------------------+
delivery_band
+--------+-----------+-----------------+----------------+---------+---------+-------------------------------------------------------+
| bandID | serviceID | name | initial_charge | min_qty | max_qty | accepted_countries |
+--------+-----------+-----------------+----------------+---------+---------+-------------------------------------------------------+
| 1 | 2 | UK Mainland | 0.00 | 0 | 0 | 225 |
| 2 | 2 | UK Offshore | 14.00 | 0 | 0 | 240 |
| 3 | 3 | Bradford Store | 0.00 | 0 | 0 | 225 |
| 4 | 1 | UK | 2.00 | 0 | 0 | 225 |
| 5 | 2 | World wide | 15.00 | 0 | 0 | 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20... |
| 6 | 1 | World wide Mail | 5.00 | 0 | 0 | 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20... |
+--------+-----------+-----------------+----------------+---------+---------+-------------------------------------------------------+
delivery_charge
+----------+--------+-----+-------+
| chargeID | bandID | qty | price |
+----------+--------+-----+-------+
| 1 | 2 | 0 | 5.00 |
| 2 | 3 | 0 | 0.00 |
| 3 | 4 | 0 | 0.00 |
| 4 | 4 | 1 | 1.00 |
| 5 | 4 | 5 | 3.00 |
| 6 | 1 | 0 | 5.95 |
| 7 | 1 | 10 | 10.95 |
| 8 | 2 | 10 | 14.00 |
| 9 | 5 | 0 | 0.00 |
| 10 | 5 | 3 | 5.00 |
| 11 | 5 | 6 | 10.00 |
| 12 | 5 | 9 | 15.00 |
| 13 | 6 | 0 | 0.00 |
| 14 | 6 | 2 | 5.00 |
| 15 | 6 | 4 | 10.00 |
| 16 | 6 | 6 | 15.00 |
+----------+--------+-----+-------+
When I tried adding the charge table as a sub query and then limiting that query it gave me NULL's for all the charge table fields
If I try the following query:
SELECT
`service`.`name`,
`charge`.`qty`,
`service`.`serviceID`,
`band`.`bandID`,
`band`.`initial_charge`,
`charge`.`chargeID`,
MAX( `charge`.`price` ) AS `price`,
`band`.`initial_charge` + `charge`.`price` AS `total_price`
FROM
`delivery_band` AS `band`
LEFT JOIN
`delivery_charge` AS `charge`
ON
`charge`.`bandID` = `band`.`bandID`
AND
`charge`.`qty` < '3'
LEFT JOIN
`delivery_service` AS `service`
ON
`service`.`serviceID` = `band`.`serviceID`
WHERE
FIND_IN_SET( '225', `band`.`accepted_countries` )
AND
(
`band`.`min_qty` >= '3'
OR
`band`.`min_qty` = '0'
)
AND
(
`band`.`max_qty` <= '3'
OR
`band`.`max_qty` = '0'
)
GROUP BY
`service`.`serviceID`
I get this returned:
+------------------+-----+-----------+--------+----------------+----------+-------+-------------+
| name | qty | serviceID | bandID | initial_charge | chargeID | price | total_price |
+------------------+-----+-----------+--------+----------------+----------+-------+-------------+
| Royal mail | 0 | 1 | 4 | 2.00 | 3 | 1.00 | 2.00 |
| APC | 0 | 2 | 1 | 0.00 | 6 | 5.95 | 5.95 |
| Collect in store | 0 | 3 | 3 | 0.00 | 2 | 0.00 | 0.00 |
+------------------+-----+-----------+--------+----------------+----------+-------+-------------+
Which looks fine in principle until you realise that the chargeID = 3 has a price of 0.00 and yet the table is showing a price of 1.00 so the values seem to have become disassociated
What I would like to do is show the highest of the two royal mail entries
You can use MAX to obtain the maximum of a given column, e.g.
SELECT … MAX(charge.price) … FROM …
If you absolutely need the other columns (like charge.chargeID) to match, things will become a lot more complicated. So make sure you actually need that. For details on the general idea behind this kind of query, have a closer look at Select one value from a group based on order from other columns. Adapting this answer by #RichardTheKiwi, I came up with the following query:
SELECT s.name,
c.qty,
s.serviceID,
b.bandID,
b.initial_charge,
c.chargeID,
c.price,
b.initial_charge + c.price AS total_price
FROM delivery_band AS b,
delivery_service AS s,
(SELECT chargeID, price, qty,
#rowctr := IF(bandId = #lastBand, #rowctr+1, 1) AS rowNumber,
#lastBand := bandId AS bandId
FROM (SELECT #rowctr:=0, #lastBand:=null) init,
delivery_charge
WHERE qty < 3
ORDER BY bandId, price DESC
) AS c
WHERE FIND_IN_SET(225, b.accepted_countries)
AND (b.min_qty >= 3 OR B.min_qty = 0)
AND (b.max_qty <= 3 OR B.max_qty = 0)
AND s.serviceID = b.serviceID
AND c.bandID = b.bandID
AND c.rowNumber = 1
See this fiddle for the corresponding output. Note that I only do inner queries, not left queries, since that seems sufficient for the query in question, and keeps things a lot more readable so you can concentrate on the important parts, i.e. those involving rowNumber. The idea is that the subquery generates row numbers for the items of the same band, resetting them for the next band. When you select only rows with rowNumber being 1, you only get the highest price, with all other columns associated with that.

Difficulty in resolving union query

I have 2 tables:
S_tbl
====================
id | barcode | qty |
====================
1 | 1234 | 10 |
1 | 111 | 5 |
1 | 1234 | 10 |
K_tbl
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
I run this query:
SELECT K_Tbl.id, K_Tbl.barcode, K_Tbl.Qty, K_Tbl.NewQty
FROM K_Tbl where K_Tbl.id = 1
UNION ALL
SELECT S_Tbl.id, S_Tbl.barcode, S_Tbl.Qty, '0' as NewQty
FROM S_Tbl where S_Tbl.id = 1
and I get this:
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 0 |
1 | 111 | 5 | 0 |
How to merge same lines that the result will be like this:
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 20 |
1 | 111 | 5 | 0 |
EDIT:
i add the line: 1 | 1234 | 10 | to S_Tbl
what i need to change in the query:
SELECT K_Tbl.id, K_Tbl.barcode, K_Tbl.Qty, K_Tbl.NewQty
FROM K_Tbl where K_Tbl.id = 1
UNION
SELECT S_Tbl.id, S_Tbl.barcode, S_Tbl.Qty, K_Tbl.NewQty
FROM S_Tbl
left join K_Tbl on S_Tbl.id=K_Tbl.id and S_Tbl.barcode=K_Tbl.barcode
where S_Tbl.id = 1
that i'll see
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 1234 | 10 | 20 |
1 | 111 | 5 | 0 |
Right now I see:
=============================
id | barcode | qty | newQty |
=============================
1 | 1234 | 10 | 20 |
1 | 111 | 5 | 0 |
SELECT K_Tbl.id, K_Tbl.barcode, K_Tbl.Qty, K_Tbl.NewQty
FROM K_Tbl where K_Tbl.id = 1
UNION
SELECT S_Tbl.id, S_Tbl.barcode, S_Tbl.Qty, K_Tbl.NewQty
FROM S_Tbl
left join K_Tbl on S_Tbl.id=K_Tbl.id and S_Tbl.barcode=K_Tbl.barcode
where S_Tbl.id = 1
SQL FIDDLE
I am sure this Query will work from MS-ACCES
Use UNION instead of UNION ALL - slower, but cares about the duplicates and removes them. Refer to MSDN doc: http://msdn.microsoft.com/en-us/library/office/bb208962(v=office.12).aspx
By default, no duplicate records are returned when you use a UNION
operation; however, you can include the ALL predicate to ensure that
all records are returned. This also makes the query run faster.
And it is also same in Oracle or MSSQL.