Ok so I want to find all the rows with the same value in. (Or at least a pair)
I.E.
James| 19.193.283.19
John| 20.134.232.344
Jack| 19.193.283.19
Jonny| 19.193.283.19
I would want it to return rows James, Jack and Jonny -as more than one row has the IP '19.193.283.19' in it.
I tried doing what the other similar question answered:
select *
from `Zombie`
group by `Ip`
having count(*) > 1
order by `Ip` desc
But it just returned 1 row with a pair or more of the similar 'Ip' I want every row.
How would I modify the SQL so it returns all indisinct rows?
Thanks alot.
You could use an exists subquery to find all rows that have a matching row with the same Ip:
select *
from YourTable as yt1
where exists
(
select *
from YourTable as yt2
where yt1.name <> yt2.name
and yt1.Ip = yt2.Ip
)
Sorting by the number of rows with the same Ip can be done with a self-join, like:
select yt1.name
, yt1.Ip
from YourTable as yt1
join YourTable as yt2
on yt1.name <> yt2.name
and yt1.Ip = yt2.Ip
group by
yt1.name
, yt1.Ip
order by
count(yt2.name) desc
Another way would be to join your table with the subquery you already have used (to find ips existing in more than one row):
SELECT t.name
, t.Ip
FROM
YourTable AS t
JOIN
( SELECT Ip
, COUNT(*) AS cnt
FROM YourTable
GROUP BY Ip
HAVING COUNT(*) > 1
) AS td
ON td.Ip = t.Ip
ORDER BY
td.cnt DESC
, t.Ip
, t.name
Related
Having the following tables
Post(*id, name, description, cat, publish_date)
Category(*id, name)
It is possible in ONE query to get (max) the first N element of each different category?
Assuming that N=3, i'd need the following result:
Result set:
["1", "Name1","Descr","cat1"]
["2", "Name1","Descr","cat1"]
["3", "Name1","Descr","cat1"]
["10","Name1","Descr","cat2"]
["20","Name1","Descr","cat2"]
["22","Name1","Descr","cat2"]
["25","Name1","Descr","cat3"]
["30","Name1","Descr","cat3"]
["19","Name1","Descr","cat3"]
And so on.
I need this, to get the first N article of EACH category, with one query (so without ask for a specific category but for all category in table)
It is possible? If yes what's the right query?
This query will do what you need. If any category has less than 3 post it will still work.
SELECT P.id,P.name,P.description,C.name
FROM Post P
LEFT JOIN Category C
ON P.type = C.id
WHERE FIND_IN_SET(P.id,
(
SELECT GROUP_CONCAT(ids) FROM
(SELECT SUBSTRING_INDEX(GROUP_CONCAT(id),',',3) as ids
FROM Post
GROUP BY type
) AS foo
GROUP BY ''
)
)
Here is a working SQL Fiddle
UPDATE
In response to your comment and updated question:
SELECT P.id,P.name,P.description,P.publish_date,C.name
FROM Post P
LEFT JOIN Category C
ON P.type = C.id
WHERE FIND_IN_SET(P.id,
(
SELECT GROUP_CONCAT(ids) FROM
(SELECT SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY publish_date DESC),',',3) as ids
FROM Post
GROUP BY type
) AS foo
GROUP BY ''
)
)
You can use UNION to join multiple queries into one. This assumes that you know what type you are selecting for each set.
SELECT * FROM
(
SELECT * FROM T1 WHERE type='Type1' ORDER BY id DESC LIMIT 3
) DUMMY1
UNION ALL
SELECT * FROM
(
SELECT * FROM T1 WHERE type='Type2' ORDER BY id DESC LIMIT 3
) DUMMY2
UNION ALL
SELECT * FROM
(
SELECT * FROM T1 WHERE type='Type3' ORDER BY id DESC LIMIT 3
) DUMMY3
The DUMMY table aliases are needed to allow ordering within each subquery.
Is there a way to tell MySQL that while making something like this
SELECT id, MAX(seq) FROM t1 GROUP BY ident;
I can also get the id value? I know I shouldn't be using id if it's not in a group by but I feel like its strange to make a multi pass to get the row ids with the maximum seq field when it already passed it. So what is the most effective way to do this? id is the primary key
SELECT a.*
FROM tableName
INNER JOIN
(
SELECT ident, MAX(seq) seq
FROM tableName
GROUP BY ident
) b ON a.ident = b.ident AND
a.seq = b.seq
Mabye:
SELECT MAX(a.seq), (SELECT id FROM t1 as b where b.ident=a.ident AND MAX(a.seq) = b.seq LIMIT 1) as id FROM t1 AS a GROUP BY a.ident;
Fiddle
Try using self-join:
SELECT t1.* FROM MyTable t1
JOIN
(SELECT ident, MAX(seq) AS MAX_Seq
FROM MyTable
GROUP BY ident
) t2
ON t1.seq = t2.MAX_Seq
AND t1.ident = t2.ident
See this sample SQLFiddle
What is seq exactly ?
I guess you can also order your results ?
SELECT id FROM t1 GROUP BY ident ORDER BY seq DESC
Regarding to the others answer, seq is in another table ?
Here is my data. I want to take 6 rows, but I want all HeadlineCategoryId's to be unique in my result list. If I select the top 6 I would take 2 rows from HeadlineCategoryID 20 (6,2). Do you have any suggestions about it?
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT HeadlineCategoryID, MAX(Creation) max_date
FROM TableName
GROUP BY HeadlineCategoryID
) b ON a.HeadlineCategoryID = b.HeadlineCategoryID AND
a.Creation = b.max_date
ORDER BY a.Creation DESC -- << specify here how are you going to sort
LIMIT 6 -- the records you want to get
UPDATE 1
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT HeadlineCategoryID, MAX(NewsID) max_id
FROM TableName
GROUP BY HeadlineCategoryID
) b ON a.HeadlineCategoryID = b.HeadlineCategoryID AND
a.NewsID = b.max_id
ORDER BY a.Creation DESC -- << specify here how are you going to sort
LIMIT 6 -- the records you want to get
It looks like you want the six most recent records, but unique by HeadlineCategoryId. If so, this will work:
select top 6 NewsId, Creation, HeadlineCategoryId
from (select t.*,
row_number() over (partition by HeadlineCategoryId order by Creation desc) as seqnum
from t
) t
where seqnum = 1
As a note . . . This question originally indicated that it was using SQL Server, not MySQL. The solution in MySQL is not as simple. Here is one method with not exists:
select NewsId, Creation, HeadlineCategoryId
from t
where not exists (select 1
from t t2
where t2.HeadlineCategoryId = t.HeadlineCategoryId and
t2.id < t.id)
limit 6
The not exists portion is saying "where there is no other record with a larger id for a given headline category".
That is a picture of my table.
I must select "Fastanumer" of all cars where "Tegund" is the most common value (which is Toyota in this example)
This is the code i tried
SELECT Fastanumer FROM `Bill`
WHERE Tegund =
(SELECT MAX(y.cnt) FROM (SELECT COUNT(Tegund) AS cnt FROM Bill ) AS y)
Which i had to work pretty hard to figure out only to end up beating myself in the head over the fact that MAX will only turn into a number. (And since Tegund isn't a list of numbers...)
Is this even possible? How can i do this?
I guess it should work this way:
SELECT Fastanumer
FROM `Bill`
WHERE Tegund = (
SELECT Tegund
FROM (
SELECT Tegund,COUNT(*) FROM Bill GROUP BY Tegund ORDER BY COUNT(*) DESC LIMIT 1
) t1
)
Or even like this:
SELECT Fastanumer
FROM `Bill`
WHERE Tegund = (
SELECT Tegund FROM Bill GROUP BY Tegund ORDER BY COUNT(*) DESC LIMIT 1
)
Here's my solution:
SELECT Bill.*
FROM Bill
WHERE Tegund IN (
SELECT Tegund
FROM Bill
GROUP BY Tegund
HAVING COUNT(*) = (
SELECT MAX(cnt) FROM (
SELECT COUNT(*) cnt
FROM Bill
GROUP BY Tegund
) s
)
)
A little more complicated than others, but if more than one Tegund shares the same number of rows, this query will show all Tegunds which are the most common.
Please see fiddle here or here.
What you want to do first is figure out which Tegund appears the most in your table. That is what the subquery is doing. Then you will select the Fastanumer which matches that Tegund.
SELECT DISTINCT Fastanumer
FROM 'BILL'
WHERE Tegund = (
SELECT TOPT 1 Tegund,
COUNT(*) as Count
FROM `BILL`
GROUP BY Tegund
ORDER BY Count DESC)
Depends on the DB (and associated SQL). Try
select fastanumber from bill
inner join
(select count(*) as cnt, tegund from Bill group by tegund) grpby
on bill.tegund = grpby.tegund
and grpby.cnt = (select max(cnt) from (select count(*) as cnt, tegund from Bill group by tegund))
how can i make something like this work?
INSERT INTO age.page(domain,title_count,youtube_count,ipaddress,updated)
SELECT * FROM
(
SELECT domain,
COUNT(domain) AS titlecount,
(SELECT COUNT(*) FROM table2 WHERE title = table1.title) AS YoutubeCount, ipaddress
NOW() AS timeNow
FROM table1
GROUP BY domain
ORDER BY title DESC
) a;
I want to use a subquery to get a count of a different table but use the same field from the main query.
the reason i want to do this is so i dont have to run two queries instead its only one.
You can do this COUNT in a subquery and then JOIN it with the first table:
INSERT INTO age.page(domain, title_count, youtube_count, ipaddress, updated)
SELECT * FROM
(
SELECT
domain,
COUNT(domain) AS titlecount,
t2.titlecount AS YoutubeCount,
ipaddress,
NOW() AS timeNow
FROM table1
INNER JOIN
(
SELECT title, COUNT(*) Titlecount
FROM table2
GROUP BY title
) AS t2 ON t2.title = table1.title
GROUP BY domain
ORDER BY table1.title DESC
) a;