I've this query.
SELECT
d.gid, d.channel_id
FROM channels, (
SELECT
gigs.id as gid, gigs.channel_id
FROM gigs
ORDER BY gigs.id DESC
LIMIT 1
) as d
WHERE d.channel_id = channels.id
LIMIT 10
I was hoping to get one gid for each channels.id, but instead it only returns one column. Why is that?
Gigs table
+---------+------------+
| id | channel_id |
+---------+------------+
| 150661 | 6 |
| 745797 | 6 |
| 483996 | 6 |
| 3407209 | 6 |
| 1175022 | 5 |
| 3238459 | 6 |
| 711413 | 5 |
| 524758 | 5 |
| 154764 | 5 |
| 1594779 | 5 |
| 1659091 | 2 |
| 1086768 | 6 |
| 1161320 | 8 |
| 467394 | 5 |
| 2877040 | 8 |
| 2705821 | 6 |
| 1881747 | 5 |
| 901902 | 1 |
| 143322 | 6 |
| 671658 | 1 |
+---------+------------+
Channels table
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
+----+
Try this one,
SELECT a.id, b.max_ID
FROM channels a
INNER JOIN
(
SELECT channel_ID, MAX(id) max_ID
FROM gigs
GROUP BY channel_ID
) b ON a.id = b.channel_ID
SQLFiddle Demo
basically, I used INNER JOIN to show only id from channels table that has atleast on record on gigs table. If you want to show list even if there is no match on gigs table then you should use LEFT JOIN instead.
SELECT id, (SELECT id FROM Gigs WHERE channel_id = c.id ORDER BY id DESC LIMIT 1) As GigID
FROM channels c
Related
I have a table with locations and there are duplicates because there are locations with same name that belongs to different counties.
+------+-----------+-----------
| ID | location | parent_id |
+------+-----------+------------+
| 1 | Country | 0 |
| 2 | County 1 | 1 |
| 3 | County 2 | 1 |
| 4 | A | 2 |
| 5 | B | 2 |
| 6 | C | 2 |
| 7 | A | 3 |
| 8 | E | 3 |
| 9 | B | 3 |
+---- -+-----------+------------+
I would like to create and insert in column duplicate for each duplicate ID value . The result should look like this: ( Would be better to add ID in duplicate column to all duplicates excepting the one with smallest ID)
| ID | location | parent_id | duplicate|
+------+-----------+------------+----------+
| 1 | Country | 0 | |
| 2 | County 1 | 1 | |
| 3 | County 2 | 1 | |
| 4 | A | 2 | 4 |
| 5 | B | 2 | 5 |
| 6 | C | 2 | |
| 7 | A | 3 | 7 |
| 8 | E | 3 | |
| 9 | B | 3 | 9 |
+---- -+-----------+------------+---------+
I use this to list the rows:
SELECT a.* FROM mytable a
JOIN (SELECT location, COUNT(*)
FROM mytable
GROUP BY location
HAVING count(*) > 1 ) b
ON a.location= b.location
ORDER BY a.location
It looks like a window count can do what you want:
select t.*,
case when count(*) over(partition by location) > 1 then id end duplicate
from mytable t
This requires MySQL 8.0. In earlier versions, an alternative is a correlated subquery:
select t.*,
case when (select count(*) from mytable t1 where t1.location = t.location) > 1 then id end duplicate
from mytable t
I've tried the following queries but unfortunately they don't work :(.
Worth mentioning that each customer has more than one CustomerUsers
select (a.TotalJobs / b.DaysActive) from
(select count(jr.id) as TotalJobs
from jobrequests jr, customers c, customerusers cu
where jr.customeruserid=cu.id
and cu.customerid=c.id
group by c.name) as a,
(select datediff(curdate(), from_unixtime(c.CreationTime)) as DaysActive
from customers c
group by c.name) as b
Please see below the tables
Jobs:
+----+--------------+
| ID | JobRequestID |
+----+--------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
| 8 | 3 |
| 9 | 3 |
| 10 | 3 |
| 11 | 4 |
| 12 | 4 |
| 13 | 5 |
| 14 | 5 |
| 15 | 6 |
| 16 | 7 |
| 17 | 8 |
| 18 | 8 |
| 19 | 9 |
| 20 | 10 |
+----+--------------+
JobRequests:
+----+---------------+
| ID | CustomeUserID |
+----+---------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 4 |
| 8 | 4 |
| 9 | 4 |
| 10 | 5 |
| 11 | 5 |
| 12 | 5 |
| 13 | 6 |
| 14 | 6 |
| 15 | 7 |
+----+---------------+
CustomerUsers:
+----+------------+
| ID | CustomerID |
+----+------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 2 |
| 7 | 2 |
| 8 | 3 |
| 9 | 3 |
| 10 | 4 |
+----+------------+
Customers:
+----+------+--------------+
| ID | Name | CreationTime |
+----+------+--------------+
| 1 | a | 1415814194 |
| 2 | b | 1415814194 |
| 3 | c | 1415986994 |
| 4 | d | 1415986994 |
+----+------+--------------+
For the moment it returns 16 results (4X4), dividing each result from 1st sub-query to each result from the 2nd one (each of these sub-queries return 4 results). Can anyone please help me to get this to divide only 1 result from sub-query 1 to it's corespondent from sub-query 2?
Thank you in advance.
I suspect that you can do what you want this a query like this:
select c.name, count(*) / (datediff(curdate(), from_unixtime(c.CreationTime))
from customerusers cu join
jobrequests jr
on jr.customeruserid = cu.id join
customers c
on cu.customerid = c.id
group by c.name;
I don't see why you need two subqueries for this.
I'm guessing you need to join your results together -- as currently written, you're producing a cartesian product.
Try something like this adding c.id to each subquery (it's better to group by it presumably rather than the name):
select (a.TotalJobs / b.DaysActive)
from (
select c.id,
count(jr.id) as TotalJobs
from jobrequests jr
join customers c on jr.customeruserid=cu.id
join customerusers cu on cu.customerid=c.id
group by c.id) a join (
select c.id,
datediff(curdate(), from_unixtime(c.CreationTime)) as DaysActive
from customers c
group by c.id) b on a.id = b.id
Please note, I've updated your syntax to use the more standard join syntax.
I have a complicated ordering issue in my query.
Raw, Unordered Data:
+------+--------+-----------+
| id | job_id | action_id |
+------+--------+-----------+
| 1 | 2 | 1 |
| 2 | 2 | 2 |
| 3 | 1 | 1 |
| 4 | 2 | 3 |
| 5 | 4 | 1 |
| 6 | 1 | 2 |
| 7 | 3 | 1 |
| 8 | 3 | 2 |
| 9 | 4 | 2 |
+------+--------+-----------+
Required Ordering:
+------+--------+-----------+
| id | job_id | action_id |
+------+--------+-----------+
| 7 | 3 | 1 |
| 8 | 3 | 2 |
| | | | * blank lines added for clarity,
| 5 | 4 | 1 | not desired in actual data
| 9 | 4 | 2 |
| | | |
| 3 | 1 | 1 |
| 6 | 1 | 2 |
| | | |
| 1 | 2 | 1 |
| 2 | 2 | 2 |
| 4 | 2 | 3 |
+------+--------+-----------+
The theory behind this ordering:
the largest id is the most recently added entry
the most recent id with action_id of 1
followed by the entries with ascending action_ids that have the same job_id
then the next most recent action_id of 1
ad infinitum
EDIT: I'm not able to add columns to the table in order to aid in sorting, as I've seen in some other solutions to ordering questions.
Any help is greatly appreciated!
My best shot is this:
SELECT * FROM tbl
ORDER BY FIND_IN_SET(job_id,
(SELECT GROUP_CONCAT(job_id ORDER BY ID DESC)
FROM tbl WHERE action_id = 1));
I didn't find a way to do it easily, What do you think of the following code :
select c.id, c.job_id, c.action_id
from (select a.id, a.job_id, a.action_id, min(b.id) as related_id
from myTable a
inner join myTable b
on a.job_id=b.job_id
group by a.job_id) c
group by c.id
order by c.related_id desc, c.action_id
I've table called Products in that type is field type value might be any one of these values 1,2,3,4.
Now I'would like to get the result as
1. Group the results based on 'type'
2. And Limit the results for each group to 5.
How can I achieve this, Currently I'm using following query
SELECT
*,
(
(
CASE
WHEN product_title LIKE '%xyz%'
THEN 2
ELSE 0
END
) + (
CASE
WHEN product_description LIKE '%xyz%'
THEN 1
ELSE 0
END
)
) AS relevance
FROM
Products
WHERE (
(
product_title LIKE '%xyz%'
OR product_description LIKE '%xyz%'
)
)
AND product_available = 1
AND product_deleted <> 1
ORDER BY relevance DESC
SELECT * FROM products;
+------------+------+
| product_id | type |
+------------+------+
| 1 | 4 |
| 2 | 3 |
| 3 | 2 |
| 4 | 4 |
| 5 | 3 |
| 6 | 1 |
| 7 | 4 |
| 8 | 3 |
| 9 | 4 |
| 10 | 2 |
| 11 | 2 |
| 12 | 1 |
| 13 | 3 |
| 14 | 2 |
| 15 | 3 |
| 16 | 1 |
| 17 | 2 |
| 18 | 1 |
| 19 | 2 |
| 20 | 4 |
| 21 | 2 |
+------------+------+
SELECT x.*
FROM products x
JOIN products y
ON y.type = x.type
AND y.product_id <= x.product_id
GROUP
BY x.product_id
HAVING COUNT(*) <=3
ORDER
BY type
, product_id;
+------------+------+
| product_id | type |
+------------+------+
| 6 | 1 |
| 12 | 1 |
| 16 | 1 |
| 3 | 2 |
| 10 | 2 |
| 11 | 2 |
| 2 | 3 |
| 5 | 3 |
| 8 | 3 |
| 1 | 4 |
| 4 | 4 |
| 7 | 4 |
+------------+------+
Here's a simple one
SELECT
p.id,
p.type
FROM
Products p
WHERE
5 > (SELECT COUNT(id) from Products where id < p.id and type = p.type)
I have created the sqlfiddle for it, http://sqlfiddle.com/#!2/ab0c00/15
I'm new in SQL queries. I have a problem with the query.
I have table books:
+----+-------+--------+-----------+
| id | title | author | publisher |
+----+-------+--------+-----------+
| 1 | Book1 | 1 | 1 |
| 2 | Book2 | 1 | 2 |
| 3 | Book3 | 2 | 1 |
| 4 | Book4 | 2 | 2 |
| 5 | Book5 | 2 | 3 |
+----+-------+--------+-----------+
And I'm have another table, which contains copies of books with given book_id.
+----+---------+
| id | book_id |
+----+---------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 4 |
| 8 | 4 |
| 9 | 5 |
+----+---------+
All I need is to merge these two tables into one to have table sorted by amount of book copies.
I found solution to get table sorted by amount of book copies:
select book_copies.book_id, count(*) total_count
from book_copies
group by book_id
having count(*) > 0
order by count(*) desc;
+---------+-------------+
| book_id | total_count |
+---------+-------------+
| 1 | 3 |
| 2 | 2 |
| 4 | 2 |
| 3 | 1 |
| 5 | 1 |
+---------+-------------+
Now I don't know how to merge them.
I've tried like this:
select books.title from books
left join
(select book_copies.book_id, count(*) total_count
from book_copies
group by book_id
having count(*) > 0
order by count(*) desc)
as total_table on books.id = total_table.book_id;
But all I get was this:
+-------+
| title |
+-------+
| Book1 |
| Book2 |
| Book3 |
| Book4 |
| Book5 |
+-------+
Could you help me please?
EDIT: by merging I meant smth like this:
+-------+--------+-----------+-----+
| title | author | publisher | tot |
+-------+--------+-----------+-----+
| Book1 | 1 | 1 | 3 |
| Book2 | 1 | 2 | 2 |
| Book4 | 2 | 2 | 2 |
| Book3 | 2 | 1 | 1 |
+-------+--------+-----------+-----+
Many thanks to #Marco for the answer!
Dmitriy
I think you could try:
SELECT b.title, b.author, b.publisher, COUNT(bc.book_id) AS tot
FROM books b LEFT JOIN book_copies bc
ON b.id = bc.book_id
GROUP BY b.id
EDITED:
If you want sort, you can try
SELECT * FROM
(SELECT b.title, b.author, b.publisher, COUNT(bc.book_id) AS tot
FROM books b LEFT JOIN book_copies bc
ON b.id = bc.book_id
GROUP BY b.id) g
ORDER BY g.tot DESC