How to take unique IDs of the following DISTINCT query? - sql

I have this table:
id | description | URL | role
1 | desc_1 | url_1 | 1
2 | desc_1 | url_1 | 2
3 | desc_2 | url_2 | 1
4 | desc_2 | url_2 | 2
I want to get the following result
id | description | URL
1 | desc_1 | url_1
3 | desc_2 | url_2
I already tried this but to no avail
SELECT DISTINCT(description), id FROM table GROUP BY description

SELECT MAX(id),descritpion,URL GROUP BY description,URL
or
SELECT MIN(id),descritpion,URL GROUP BY description,URL
depends if u want higher or lowest id.

SELECT MIN(id)
,descritpion
,URL
FROM myTable
GROUP BY description
,URL

Group By clause is generally used with aggregate functions. There are five aggregate functions in SQL. MIN , MAX , COUNT , SUM and AVG. In your situation you can use MIN or MAX functions to accomplish your work.
select MIN(id),descritpion,URL from table GROUP BY description , URL
or
select MAX(id),descritpion,URL from table GROUP BY description , URL

SELECT t.id, t.description, t.URL
FROM
(
SELECT id, description, URL,
ROW_NUMBER() OVER (PARTITION BY description, URL ORDER BY role) rn
FROM yourTable
) t
WHERE t.rn = 1

Using MIN Clause to get result :
SELECT MIN(id),description,URL
FROM table GROUP BY description,URL

Related

How to SELECT in SQL based on a value from the same table column?

I have the following table
| id | date | team |
|----|------------|------|
| 1 | 2019-01-05 | A |
| 2 | 2019-01-05 | A |
| 3 | 2019-01-01 | A |
| 4 | 2019-01-04 | B |
| 5 | 2019-01-01 | B |
How can I query the table to receive the most recent values for the teams?
For example, the result for the above table would be ids 1,2,4.
In this case, you can use window functions:
select t.*
from (select t.*, rank() over (partition by team order by date desc) as seqnum
from t
) t
where seqnum = 1;
In some databases a correlated subquery is faster with the right indexes (I haven't tested this with Postgres):
select t.*
from t
where t.date = (select max(t2.date) from t t2 where t2.team = t.team);
And if you wanted only one row per team, then the canonical answer is:
select distinct on (t.team) t.*
from t
order by t.team, t.date desc;
However, that doesn't work in this case because you want all rows from the most recent date.
If your dataset is large, consider the max analytic function in a subquery:
with cte as (
select
id, date, team,
max (date) over (partition by team) as max_date
from t
)
select id
from cte
where date = max_date
Notionally, max is O(n), so it should be pretty efficient. I don't pretend to know the actual implementation on PostgreSQL, but my guess is it's O(n).
One more possibility, generic:
select * from t join (select max(date) date,team from t
group by team) tt
using(date,team)
Window function is the best solution for you.
select id
from (
select team, id, rank() over (partition by team order by date desc) as row_num
from table
) t
where row_num = 1
That query will return this table:
| id |
|----|
| 1 |
| 2 |
| 4 |
If you to get it one row per team, you need to use array_agg function.
select team, array_agg(id) ids
from (
select team, id, rank() over (partition by team order by date desc) as row_num
from table
) t
where row_num = 1
group by team
That query will return this table:
| team | ids |
|------|--------|
| A | [1, 2] |
| B | [4] |

Get row which matched in each group

I am trying to make a sql query. I got some results from 2 tables below. Below results are good for me. Now I want those values which is present in each group. for example, A and B is present in each group(in each ID). so i want only A and B in result. and also i want make my query dynamic. Could anyone help?
| ID | Value |
|----|-------|
| 1 | A |
| 1 | B |
| 1 | C |
| 1 | D |
| 2 | A |
| 2 | B |
| 2 | C |
| 3 | A |
| 3 | B |
In the following query, I have placed your current query into a CTE for further use. We can try selecting those values for which every ID in your current result appears. This would imply that such values are associated with every ID.
WITH cte AS (
-- your current query
)
SELECT Value
FROM cte
GROUP BY Value
HAVING COUNT(DISTINCT ID) = (SELECT COUNT(DISTINCT ID) FROM cte);
Demo
The solution is simple - you can do this in two ways at least. Group by letters (Value), aggregate IDs with SUM or COUNT (distinct values in ID). Having that, choose those letters that have the value for SUM(ID) or COUNT(ID).
select Value from MyTable group by Value
having SUM(ID) = (SELECT SUM(DISTINCT ID) from MyTable)
select Value from MyTable group by Value
having COUNT(ID) = (SELECT COUNT(DISTINCT ID) from MyTable)
Use This
WITH CTE
AS
(
SELECT
Value,
Cnt = COUNT(DISTINCT ID)
FROM T1
GROUP BY Value
)
SELECT
Value
FROM CTE
WHERE Cnt = (SELECT COUNT(DISTINCT ID) FROM T1)

PostgreSQL - MAX value for every user

I have a table
User | Phone | Value
Peter | 0 | 1
Peter | 456 | 2
Peter | 456 | 3
Paul | 456 | 7
Paul | 789 | 10
I want to select MAX value for every user, than it also lower than a tresshold
For tresshold 8, I want result to be
Peter | 456 | 3
Paul | 456 | 7
I have tried the GROUP BY with HAVING, but I am getting
column "phone" must appear in the GROUP BY clause or be used in an aggregate function
Similar query logic works in MySQL, but I am not quite sure how to operate with GROUP BY in PostgreSQL. I dont want to GROUP BY phone.
After I have results from "juergen d" solution, I came up with this which gives me the same results faster
SELECT DISTINCT ON(user) user, phone, value
FROM table
WHERE value < 8
ORDER BY user, value DESC;
select t1.*
from your_table t1
join
(
select user, max(value) as max_value
from your_table
where value < 8
group by user
) t2 on t1.user = t2.user and t1.value = t2.max_value
Alternatively, you could use a ranking function:
select * from
(
select *, RANK() OVER (partition by [user] ORDER BY t.value desc ) as value_rank from test_table as t
where t.value < 8
) as t1
where value_rank = 1

SQL Server : select from duplicate columns where date newest

I have inherited a SQL Server table in the (abbreviated) form of (includes sample data set):
| SID | name | Invite_Date |
|-----|-------|-------------|
| 101 | foo | 2013-01-06 |
| 102 | bar | 2013-04-04 |
| 101 | fubar | 2013-03-06 |
I need to select all SID's and the Invite_date, but if there is a duplicate SID, then just get the latest entry (by date).
So the results from the above would look like:
101 | fubar | 2013-03-06
102 | bar | 2013-04-04
Any ideas please.
N.B the Invite_date column has been declared as a nvarchar, so to get it in a date format I am using CONVERT(DATE, Invite_date)
You can use a ranking function like ROW_NUMBER or DENSE_RANK in a CTE:
WITH CTE AS
(
SELECT SID, name, Invite_Date,
rn = Row_Number() OVER (PARTITION By SID
Order By Invite_Date DESC)
FROM dbo.TableName
)
SELECT SID, name, Invite_Date
FROM CTE
WHERE RN = 1
Demo
Use Row_Number if you want exactly one row per group and Dense_Rank if you want all last Invite_Date rows for each group in case of repeating max-Invite_Dates.
select t1.*
from your_table t1
inner join
(
select sid, max(CONVERT(DATE, Invite_date)) mdate
from your_table
group by sid
) t2 on t1.sid = t2.sid and CONVERT(DATE, t1.Invite_date) = t2.mdate
select
SID,name,MAX(Invite_date)
FROM
Table1
GROUP BY
SID
http://sqlfiddle.com/#!2/6b6f66/1

SQL distinct rows and count

I have a table like this:
Id CookieId
--------------------------------
4 13ab1dc1bac-ef74565ea9ff5ba8
4 13b474728b3-6cf7bf445e311c59
4 13b474728b3-6cf7bf445e311c59
4 13a1b545ebf-20c86b23c91ad2c5
4 13a1b545ebf-20c86b23c91ad2c5
The result should be only the distinct rows:
Id CookieId
--------------------------------
4 13ab1dc1bac-ef74565ea9ff5ba8
4 13b474728b3-6cf7bf445e311c59
4 13a1b545ebf-20c86b23c91ad2c5
More of that if I can get the count of the rows would be also good.
Id count(CookieId)
-----------------------
4 3
How can I achieve this two result?
To get unique records in result use this:
SELECT DISTINCT ID, CookieId
FROM Table1
Result:
| ID | COOKIEID |
-------------------------------------
| 4 | 13ab1dc1bac-ef74565ea9ff5ba8 |
| 4 | 13b474728b3-6cf7bf445e311c59 |
| 4 | 13a1b545ebf-20c86b23c91ad2c5 |
To get count of unique CookieId use DISTINCT inside COUNT function like this:
SELECT ID, COUNT(DISTINCT CookieId) AS `COUNT`
FROM Table1
GROUP BY ID
Result:
| ID | COUNT |
--------------
| 4 | 3 |
See this SQLFiddle
First to select the distinct values use
SELECT DISTINCT CookieId, Id
FROM YourTable;
GO
This is only working because you have duplicates across two columns. To get the count of those values use
SELECT Id, COUNT(DISTINCT CookieId)
FROM YourTable;
GROUP BY Id;
GO
I hope this helps.
you can try this query
select Id,count(CookieId) from table_name group by CookieId;
select Id, CookieId, count(1) as Amount
from Table1 group by Id, CookieId
SELECT DISTINCT(`CookieId`),Id, COUNT(CookieId) FROM
`tablename` GROUP BY `CookieId`