SQL How to remove duplicates within select query? - sql

I have a table which looks like that:
As You see, there are some date duplicates, so how to select only one row for each date in that table?
the column 'id_from_other_table' is from INNER JOIN with the table above

There are multiple rows with the same date, but the time is different. Therefore, DISTINCT start_date will not work. What you need is: cast the start_date to a DATE (so the TIME part is gone), and then do a DISTINCT:
SELECT DISTINCT CAST(start_date AS DATE) FROM table;
Depending on what database you use, the type name for DATE is different.

Do you need any other information except the date? If not:
SELECT DISTINCT start_date FROM table;

You mention that there are date duplicates, but it appears they're quite unique down to the precision of seconds.
Can you clarify what precision of date you start considering dates duplicate - day, hour, minute?
In any case, you'll probably want to floor your datetime field. You didn't indicate which field is preferred when removing duplicates, so this query will prefer the last name in alphabetical order.
SELECT MAX(owner_name),
--floored to the second
dateadd(second,datediff(second,'2000-01-01',start_date),'2000-01-01') AS StartDate
From MyTable
GROUP BY dateadd(second,datediff(second,'2000-01-01',start_date),'2000-01-01')

Select Distinct CAST(FLOOR( CAST(start_date AS FLOAT ) )AS DATETIME) from Table

If you want to select any random single row for particular day, then
SELECT * FROM table_name GROUP BY DAY(start_date)
If you want to select single entry for each user per day, then
SELECT * FROM table_name GROUP BY DAY(start_date),owner_name

here is the solution for your query returning only one row for each date in that table
here in the solution 'tony' will occur twice as two different start dates are there for it
SELECT * FROM
(
SELECT T1.*, ROW_NUMBER() OVER(PARTITION BY TRUNC(START_DATE),OWNER_NAME ORDER BY 1,2 DESC ) RNM
FROM TABLE T1
)
WHERE RNM=1

You have to convert the "DateTime" to a "Date". Then you can easier select just one for the given date no matter the time for that date.

Related

Select distinct and add one to that value

I have a database with a column containing year-week in this format "202030, 202031" and so on. However the weeks are US-format and to be in Swedish format I need to add 1 to this integer.
I have this query that works but gives me the "wrong week":
Select distinct date_week FROM table Order by date_week desc
I have tried this without success:
Select distinct date_week +1 FROM table Order by date_week desc
How do I add +1 to the volumes in that date-week column?
Does this do what you want?
select date_week + 1
from table
group by date_week
order by date_week desc;
You don't specify the issue with your query, but it might simply be the select distinct.

How to select the first observation in a category in PostgreSQL

My table contains different house IDs(dataid), time of observation(readtime), meter reading Basic Output
And the query is as follows Query statement :
select *
from university.gas_ert
where readtime between '01/01/2014' and '01/02/2014'
I am trying to get only the first observation of each day of all the dataids between the time span. I have tried GROUP BY, but it doesn't seem working.
Distinct ON could make your query much more simple.. More read in Documentation
Definition :
Keeps only the first row of each set of rows where the given
expressions evaluate to equal. Note that the “first row” of each set
is unpredictable unless ORDER BY is used to ensure that the desired
row appears first.
SELECT
DISTINCT ON (meter_value) meter_value,
dataid,
readtime
FROM
university.gas.ert
WHERE
readtime between '2014-01-01' and '2014-01-02'
ORDER BY
meter_value,
readtime ASC;
If you want one row for each unique dataid within the time range, you should use the DISTINCT ON construction. The following query will give you a row for each dataid for each day in the range described in the WHERE clause and lets you extend the range if you want to return rows for each day x dataid combination.
select distinct on(dataid, date_trunc('day', readtime)) *
from university.gas_ert
where readtime between '2014-01-01' and '2014-01-02'
order by dataid, date_trunc('day', readtime) asc
You can take a look at window functions to help out in this. ROW_NUMBER.
GROUP the records on the basis of day using date_trunc(ie without the time component) and then rank them on the basis of readtime asc
select *
from (
select *
,row_number() over(partition by date_trunc('day',a.readtime) order by a.readtime asc ) as rnk
from university.gas_ert a
)x
where x.rnk=1

SQL: select next available date for multiple records

I have an oracle DB.
My table has ID and DATE columns (and more).
I would like to select for every ID the next available record after a certain date. For only one ID the query would be:
SELECT * FROM my_table
WHERE id = 1 AND date >= '01.01.2018'
(just ignoring the to_date() function)
How would that look like for multiple IDs? And I do want to SELECT *.
Thanks!
We can use ROW_NUMBER here:
SELECT ID, date -- and maybe other columns
FROM
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date) rn
FROM my_table
WHERE date >= date '2018-01-01'
) t
WHERE rn = 1
The idea here is to assign a row number to each ID partition, starting with the earliest date which occurs after the cutoff you specify. The first record from each partition would then be the immediate next date, assuming it exists.

Loop through dates

We have a table to keep track of items in a warehouse:
-------------------------
ID DATEIN DATEOUT
-------------------------
What we need is a list of the amount of items in the warehouse per week.
This is how far we've gotten:
SELECT
COUNT (ID)
FROM
table
WHERE
table.DATEIN<=#somedate1#
AND
(
table.DATEOUT>#somedate1#
OR
table.DATEOUT IS NULL
)
This gives us the amount of items in the warehouse on date #somedate1#. However, we need a list of the amount per week. (keeping in mind that it's possible that some items stay in the warehouse for months)
The tricky part isn't the week, we can use DATEPART ("ww", #somedate1#), but looping through the dates.
Any ideas?
Have you tried?
SELECT
DATEPART("ww","D"),COUNT (ID)
FROM
(
SELECT Table.DATEIN as D
FROM table
WHERE table.DATEIN<=#somedate1# AND ( table.DATEOUT>#somedate1# OR table.DATEOUT IS NULL)
UNION ALL
SELECT Table.DATEOUT as D
FROM table
WHERE table.DATEIN<=#somedate1# AND ( table.DATEOUT>#somedate1# OR table.DATEOUT IS NULL)
)
GROUP BY DATEPART("ww","D")
First you need to make an UNION to make sure you have all DATEIN and DATEOUT, then you can GROUP BY
Here's what we've come up with so far.
This code gives a list of all dates where an item came into the warehouse or left. These are the dates we need to apply the code in my first post to. I.e. we need to loop through these dates where for each iteration the next date is used as #somedate1#
SELECT
table.DATEIN AS DATE
FROM
table
GROUP BY
table.DATEIN
UNION
SELECT
table.DATEOUT AS DATE
FROM
table
WHERE
table.DATEOUT NOT IN (
SELECT
table.DATEIN
FROM
table
GROUP BY
table.DATEIN
)
GROUP BY
table.DATEOUT
We're stuck at how we can loop through them though. Everything we try gives weird results that we're not expecting.
We got it! The answer was staring us right in the face the whole time. This does the trick:
SELECT
COUNT (table1.ID),
table2.DATE
FROM
table1,
(
SELECT
table1.DATEIN AS DATE
FROM
table1
GROUP BY
table1.DATEIN
UNION
SELECT
table1.DATEOUT AS DATE
FROM
table1
WHERE
table1.DATEOUT NOT IN (
SELECT
table1.DATEIN
FROM
table1
GROUP BY
table1.DATEIN
)
GROUP BY
table1.DATEOUT
) table2
WHERE
table1.DATEIN<=table2.DATE
AND
(
table1.DATEOUT>table2.DATE
OR
table1.DATEOUT IS NULL
)
GROUP BY
table2.DATE

Get latest updated records

I have an "Observation" table in SQL Server 2008. This table has a locationId column for a bunch of geographic locations, a few columns for observation details and a column for latest updated date.
Every week, a new observation record for each location is appended. So a location has many occurrences in the table.
What I want to achieve is to be able to get the most recent observation record for each location.
Can anyone help with any idea?
select * from observation where date=(select max(date) from observation)
or
select top 1 * from observation order by date desc
select a.* from observations a inner join
(select locationid ,max(updateddate) dates from observations
group by locationid) b
on a.locationid=b.locationid
and a.updateddate=b.dates
Run query
select * from Observation
group by location
order by viewdate desc
Please also give the full details about table and what you want to get.
EDIT : Backtick removed.
Add a column to your table with a datatype of [timestamp]
execute the following code:
select top(10) * from yourtablename order by columanname desc
Note:columanname should be the column you add with a timestamp type
Use the Getdate function as I used as below.
select * from TBL_MP_QC_CustomerWiseCOA_Master order by getdate() desc