Hi I have a table like so:
SN | User | is_borrowed | date
105 | 1 | 1 |2019-1-1
105 | 1 | 0 |2019-2-1
105 | 1 | 1 |2019-3-1
106 | 2 | 1 |2019-4-1
107 | 1 | 1 |2019-5-1
106 | 2 | 0 |2019-6-1
106 | 2 | 1 |2019-8-1
107 | 1 | 0 |2019-9-1
107 | 2 | 1 |2019-10-1
Wanted output is to show what is borrowed (not returned) and user=1:
SN | User | is_borrowed | date
105 | 1 | 1 |2019-3-1
Output for User=2 and borrowed (not returned):
SN | User | is_borrowed | date
106 | 2 | 1 |2019-8-1
107 | 2 | 1 |2019-10-1
In summary I want a list of devices currently borrowed that are not returned for each user. Sadly nothing comes to my mind tho :/
looking to your expected result seems you are looking for the max(date) for SN, user where is_borrowed = 1
select SN, user, is_borrowed, max(date)
from my_table
where is_borrowed = 1
group by SN, user, is_borrowed
or for the device actual borrowed
Select * from my_table m
inner join t (
select SN, is_borrowed, max(date) max_date
from my_table
where is_borrowed = 1
group by SN, is_borrowed
) t on t.SN = m.SN AND t.max_date = m.date
SELECT t.sn, t.user, t.is_borrowed, t.date
FROM TABLE_NAME t
WHERE t.is_borrowed = 1
AND t.date =
(
SELECT MAX(x.date)
FROM TABLE_NAME x
WHERE x.user = t.user
)
AND (
SELECT xx.is_borrowed
FROM TABLE_NAME xx
WHERE t.sn = xx.sn
AND t.date < xx.date
) <> 0
;
I have a table with a following structure and data:
id | type | title
--------------------------
1 | 1 | test 1
2 | 1 | test 2
3 | 2 | test 3
4 | 2 | test 4
5 | 1 | test 5
I need to group neighbor rows with the same type field values.
So the result should be like:
type |
------
1 |
2 |
1 |
Thanks in advance.
this should do the trick.. using user defined variables.
SELECT
type
FROM(
SELECT
type,
if(#a = type, #b, #b := #b + 1) as grouping_col,
#a := type
FROM testing
JOIN (select #a := 1, #b := 0) as temp
) as t
GROUP BY grouping_col;
SQL FIDDLE to play with
Here's one way - although a solution using variables will scale better...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,type INT NOT NULL
,title VARCHAR(12) NOT NULL
);
INSERT INTO my_table VALUES
(1,1,'test 1'),
(3,1,'test 2'),
(4,2,'test 3'),
(7,2,'test 4'),
(9,1,'test 5');
SELECT * FROM my_table;
+----+------+--------+
| id | type | title |
+----+------+--------+
| 1 | 1 | test 1 |
| 3 | 1 | test 2 |
| 4 | 2 | test 3 |
| 7 | 2 | test 4 |
| 9 | 1 | test 5 |
+----+------+--------+
SELECT a.id start
, MIN(c.id) End
, a.type
FROM
( SELECT x.*,COUNT(*) rank FROM my_table x JOIN my_table y ON y.id <= x.id GROUP BY x.id) a
LEFT
JOIN
( SELECT x.*,COUNT(*) rank FROM my_table x JOIN my_table y ON y.id <= x.id GROUP BY x.id) b
ON b.type = a.type
AND b.rank = a.rank - 1
LEFT
JOIN
( SELECT x.*,COUNT(*) rank FROM my_table x JOIN my_table y ON y.id <= x.id GROUP BY x.id) c
ON c.type = a.type
AND c.rank >= a.rank
LEFT
JOIN
( SELECT x.*,COUNT(*) rank FROM my_table x JOIN my_table y ON y.id <= x.id GROUP BY x.id) d
ON d.type = a.type
AND d.rank = c.rank + 1
WHERE b.id IS NULL
AND c.id IS NOT NULL
AND d.id IS NULL
GROUP
BY a.id;
+-------+------+------+
| start | End | type |
+-------+------+------+
| 1 | 3 | 1 |
| 4 | 7 | 2 |
| 9 | 9 | 1 |
+-------+------+------+
This is a small snippet of my table, which currently contains ~10,000,000 rows
+---------+---------------------+-----------+----------------+
| card_id | date | avg_price | foil_avg_price |
+---------+---------------------+-----------+----------------+
| 10000 | 2014-06-28 09:05:56 | 5.02 | 10.22 |
| 20000 | 2014-06-28 09:05:54 | 14.58 | 25.10 |
| 10000 | 2014-06-29 09:05:56 | 0.00 | 19.62 |
| 20000 | 2014-06-29 09:05:54 | 14.58 | 0.00 |
| 10000 | 2014-07-01 09:05:56 | 0.00 | 19.62 |
| 20000 | 2014-07-01 09:05:54 | 0.00 | 25.10 |
+---------+---------------------+-----------+----------------+
It is a price history for cards, including what the avg_price and what the foil_avg_price was for each day or so.
I'd like to select, for a group of card id's the most recent date when the foil_avg_price was > 0, what that price was, and the most recent date that the avg_price was > 0, and what that price was. My resulting data set for the above would look something like this:
+---------+---------------------+-----------+---------------------+----------------+
| card_id | avg_date | avg_price | foil_date | foil_avg_price |
+---------+---------------------+-----------+---------------------+----------------+
| 10000 | 2014-06-28 09:05:56 | 5.02 | 2014-07-01 09:05:54 | 19.62 |
| 20000 | 2014-06-29 09:05:54 | 14.58 | 2014-07-01 09:05:54 | 25.10 |
+---------+---------------------+-----------+---------------------+----------------+
I'm sure that this involves an INNER JOIN on the same table but I can't quite get my head around it. Any help would be much appreciated.
Three steps:
Find last price date
Find last foil price date
resolve prices on these dates
So,
SELECT dates.*, price.avg_price, foilprice.foil_avg_price
FROM (
SELECT
card_id,
MAX(IF(avg_price>0, `date`, '0001-01-01')) AS avg_date,
MAX(IF(foil_avg_price>0, `date`, '0001-01-01')) AS foil_avg_date
FROM card_price
GROUP BY card_id
) AS dates
INNER JOIN card_price AS price
ON dates.card_id=price.`date`
INNER JOIN card_price AS foilprice
ON dates.card_id=foilprice.`date`
Try this query
SELECT A.card_id,max(date),MAX(avg_price), (SELECT MAX(date) FROM test WHERE card_id = A.card_id AND foil_avg_price = MAX(A.foil_avg_price)) AS date,MAX(foil_avg_price) FROM test A
GROUP BY A.card_id
How about if you had 20,000,000 rows...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(card_id INT NOT NULL
,date DATETIME NOT NULL
,price_type VARCHAR(20) NOT NULL
,price_value DECIMAL(5,2) NOT NULL
,PRIMARY KEY(card_id,date,price_type)
);
INSERT INTO my_table VALUES
(10000,'2014-06-28 09:05:56','avg_price',5.02),
(20000,'2014-06-28 09:05:54','avg_price',14.58),
(10000,'2014-06-29 09:05:56','avg_price',0.00),
(20000,'2014-06-29 09:05:54','avg_price',14.58),
(10000,'2014-07-01 09:05:56','avg_price',0.00),
(20000,'2014-07-01 09:05:54','avg_price',0.00),
(10000,'2014-06-28 09:05:56','foil_avg_price',10.22),
(20000,'2014-06-28 09:05:54','foil_avg_price',25.10),
(10000,'2014-06-29 09:05:56','foil_avg_price',19.62),
(20000,'2014-06-29 09:05:54','foil_avg_price',0.00),
(10000,'2014-07-01 09:05:56','foil_avg_price',19.62),
(20000,'2014-07-01 09:05:54','foil_avg_price',25.10);
SELECT x.*
FROM my_table x
JOIN
( SELECT card_id,price_type,MAX(date) max_date FROM my_table WHERE price_value > 0 GROUP BY card_id,price_type) y
ON y.card_id = x.card_id
AND y.price_type = x.price_type
AND y.max_date = x.date;
+---------+---------------------+----------------+-------------+
| card_id | date | price_type | price_value |
+---------+---------------------+----------------+-------------+
| 10000 | 2014-06-28 09:05:56 | avg_price | 5.02 |
| 10000 | 2014-07-01 09:05:56 | foil_avg_price | 19.62 |
| 20000 | 2014-06-29 09:05:54 | avg_price | 14.58 |
| 20000 | 2014-07-01 09:05:54 | foil_avg_price | 25.10 |
+---------+---------------------+----------------+-------------+
Try this:
SELECT a.card_id, a.avg_date, a.avg_price, b.foil_date, b.foil_avg_price
FROM (SELECT c.card_id, c.date AS avg_date, c.avg_price
FROM cards c
INNER JOIN (SELECT c.card_id, MAX(IF(c.avg_price > 0, c.date, NULL)) avg_date
FROM cards c GROUP BY c.card_id
) a ON c.card_id = a.card_id AND c.date = a.avg_date
) AS a
LEFT JOIN (SELECT c.card_id, c.date AS foil_date, c.foil_avg_price
FROM cards c
INNER JOIN (SELECT c.card_id, MAX(IF(c.foil_avg_price > 0, c.date, NULL)) foil_date
FROM cards c GROUP BY c.card_id
) a ON c.card_id = a.card_id AND c.date = a.foil_date
) AS b ON a.card_id = b.card_id ;
OR
SELECT a.card_id, a.avg_date, a.avg_price, b.foil_date, b.foil_avg_price
FROM (SELECT *
FROM (SELECT c.card_id, c.date, c.avg_price
FROM cards c WHERE c.avg_price > 0
ORDER BY c.date DESC
) AS A
GROUP BY A.date
) AS a
LEFT JOIN ( SELECT *
FROM (SELECT c.card_id, c.date, c.foil_avg_price
FROM cards c WHERE c.foil_avg_price > 0
ORDER BY c.date DESC
) AS B
GROUP BY B.date
) AS b ON a.card_id = b.card_id;
Given the table structure below, how do I select only rows having the same root and level values for a given name and user_id?
Category
+----+---------+------+------+-------+
| id | user_id | name | root | level |
+----+---------+------+------+-------+
| 1 | 10 | wzq | 1 | 1 |
| 2 | 11 | xyz | 2 | 1 |
| 3 | 10 | xyz | 2 | 2 |
| 4 | 10 | xyz | 2 | 2 |
+----+---------+------+------+-------+
What I have now also selects rows that do not have the same root and level
SELECT `c`.`id`, `c`.`user_id`, `c`.`name`, `c`.`root`, `c`.`level`
FROM `category` `c`
WHERE c.id IN (SELECT d.id FROM category AS d WHERE c.root=d.root AND c.level=d.level ) AND c.user_id = 10 AND c.name = 'xyz'
ORDER BY `c`.`id`
For the above example only the 3rd and 4th rows should be returned
Try this one for select only rows having the same root and level simply root=level
SELECT `id`, `user_id`, `name`, `root`, `level`
FROM `category`
WHERE root=level AND user_id = 10 AND `name` = 'xyz'
ORDER BY `id`
SELECT x.*
FROM my_table x
JOIN my_table y
ON y.user_id = x.user_id
AND y.root = x.root
AND y.level = x.level
AND y.id <> x.id
WHERE x.user_id = 10
try this:
SELECT *
FROM
(
SELECT root, level
FROM category
WHERE name = 'xyz' AND user_id = 10
) x JOIN category c ON x.root = c.root
I have a table with a composite primary key on EID (event ID) and start_time. I have another column called attending.
Users make their events more popular by reusing the event ID and changing the date, however, I create a new line in the database in this instance.
I would like to create a 4th column, actual_attending which is equal to the attending value minus the previous event's attending value. If their is no previous ID, the column can be null. How can I calculate this via update.
Here is a sqlfiddle as an example: http://sqlfiddle.com/#!2/43f2c5
update event e1
set e1.actual_attending = (select e1.attending - e2.attending
from event e2
where e2.eid(+) = e1.previous_eid
)
SELECT a.*
, a.attending-b.attending new_actual_attending
FROM
( SELECT x.*
, COUNT(*) rank
FROM event x
JOIN event y
ON y.eid = x.eid
AND y.start_time <= x.start_time
GROUP
BY eid, start_time
) a
LEFT
JOIN
( SELECT x.*
, COUNT(*) rank
FROM event x
JOIN event y
ON y.eid = x.eid
AND y.start_time <= x.start_time
GROUP
BY eid, start_time
) b
ON b.eid = a.eid
AND b.rank = a.rank - 1;
+-----+------------+-----------+------------------+------+----------------------+
| eid | start_time | attending | actual_attending | rank | new_actual_attending |
+-----+------------+-----------+------------------+------+----------------------+
| 1 | 2013-06-08 | 29 | NULL | 1 | NULL |
| 2 | 2013-06-09 | 72 | NULL | 1 | NULL |
| 2 | 2013-06-16 | 104 | NULL | 2 | 32 |
| 3 | 2013-06-07 | 224 | NULL | 1 | NULL |
| 3 | 2013-06-14 | 222 | NULL | 2 | -2 |
+-----+------------+-----------+------------------+------+----------------------+
http://sqlfiddle.com/#!2/43f2c5/2