Query 2 tables from 2 machines and group results - sql

I have a query that gives the right information back but I cannot figure out how to get distinct days and sum the count. below is my query and the results shows what I get back, and what I would like to have come back. I thought the union would join them and give my back the results that I wanted. I have search for quite some time and have not located any help on this topic. Any help will be appreciated. Thank you in advance.
SELECT COUNT(log_datetime) AS icount, CONVERT(varchar, log_datetime, 101) AS logdate
from openrowset('sqloledb', 'ServerName1';'UserID';'Password',
'select * from DatabaseName..TableName where field1 > 899')
group by convert(varchar, log_datetime, 101)
union
SELECT COUNT(log_datetime) AS icount, CONVERT(varchar, log_datetime, 101) AS logdate
from openrowset('sqloledb', 'ServerName2';'UserID';'Password',
'select * from DatabaseName..TableName where field1 > 899')
group by convert(varchar, log_datetime, 101)
order by logdate
Results
235 01/10/2013
312 01/10/2013
3091 01/11/2013
3197 01/11/2013
3339 01/12/2013
3536 01/12/2013
Wanted Results
547 01/10/2013
6288 01/11/2013
6875 01/12/2013

You can try this
SELECT SUM(icount) AS icount, logdate FROM
(
SELECT COUNT(log_datetime) AS icount, CONVERT(varchar, log_datetime, 101) AS logdate
FROM openrowset('sqloledb', 'ServerName1';'UserID';'Password',
'select * from DatabaseName..TableName where field1 > 899')
GROUP BY convert(varchar, log_datetime, 101)
UNION ALL
SELECT COUNT(log_datetime) AS icount, CONVERT(varchar, log_datetime, 101) AS logdate
FROM openrowset('sqloledb', 'ServerName2';'UserID';'Password',
'select * from DatabaseName..TableName where field1 > 899')
GROUP BY convert(varchar, log_datetime, 101)
) AS tbl
GROUP BY logdate
ORDER BY logdate
And here is sqlfiddle

SELECT count(1) icount, AA.logdate FROM
(
SELECT CONVERT(varchar, log_datetime, 101) AS logdate
from openrowset('sqloledb', 'ServerName1';'UserID';'Password',
'select * from DatabaseName..TableName where field1 > 899')
union all
SELECT CONVERT(varchar, log_datetime, 101) AS logdate
from openrowset('sqloledb', 'ServerName2';'UserID';'Password',
'select * from DatabaseName..TableName where field1 > 899')
) AA
group by AA.logdate order by AA.logdate

I believe peterm's answer is correct, just wanted to add a note as to why.
With SQL, you have to think in sets. You are creating two unique sets of data, and, using UNION, combining them. However, your GROUP BY statements are within each set, not the combination. Hence, the multiple row results. By wrapping everything with another SELECT statement, you are querying the combined set, and are now able to group and aggregate.

Related

Get min and max between two dates

I'm querying the following code, to get min, max and avg, but still give me a problem, because it query all rows that I have from name = 'Jose' and not the min, max, and avg.
SELECT CONVERT(CHAR(10), DATA, 120) AS DATA,
MIN([VALUE]) AS MinValue,
AVG([VALUE]) AS MedValue,
MAX([VALUE]) AS MaxValue
FROM databasename
WHERE (name = 'Jose')
GROUP BY CONVERT(CHAR(10), DATA, 120)
ORDER BY DATA ASC
Example of what I get from the first query:
Image (can't embed image)
To query two dates, I'm using the following code but it don't get any result from query.
SELECT CONVERT(CHAR(10), DATA, 120) AS DATA,
MIN([VALUE]) AS MinValue,
AVG([VALUE]) AS MedValue,
MAX([VALUE]) AS MaxValue
FROM databasename
WHERE [DATA] between '2017-02-01' AND '2018-03-10' AND name = 'Jose'
GROUP BY CONVERT(CHAR(10), DATA, 120)
ORDER BY DATA ASC
I'm using MSSQL database.
UPDATE:
I already can query between two dates, as you can see in the second query. Problem that I'm not getting only min, max and avg.
Image:
try this SQL Query Convert(DATE,'2017-02-01').
SELECT DATA AS DATA,
MIN([VALUE]) AS MinValue,
AVG([VALUE]) AS MedValue,
MAX([VALUE]) AS MaxValue
FROM databasename
WHERE [DATA] between CONVERT(DATE, '2017-02-01') AND CONVERT(DATE, '2018-03-10')
AND name = 'Jose'
GROUP BY CONVERT(DATE, '2017-02-20')
ORDER BY CONVERT(DATE, '2017-02-20') ASC
can you consider small change in your query
SELECT CONVERT(CHAR(10), DATA, 120) AS DATA,
MIN([VALUE]) AS MinValue,
AVG([VALUE]) AS MedValue,
MAX([VALUE]) AS MaxValue
FROM databasename
WHERE CONVERT(CHAR(10), DATA, 120) between CONVERT(CHAR(10), 2017 - 02 - 20, 120) AND
CONVERT(CHAR(10), 2018 - 02 - 25, 120) AND name = 'Jose'
GROUP BY CONVERT(CHAR(10), DATA, 120)
ORDER BY DATA ASC

Subqueries with update statement in sql

I have the following query:
SELECT
CONVERT(datetime, CONVERT(varchar, new_time, 101)) As day,
datepart(hh,new_time) As hour,count(*) As Total
FROM
log_table
WHERE
new_time > GETDATE() - 180
GROUP BY
CONVERT(datetime, CONVERT(varchar, new_time, 101)),datepart(dd,new_time), datepart(hh,new_time)
ORDER BY
CONVERT(datetime, CONVERT(varchar, new_time, 101)), datepart(hh,new_time));
I need to update the table 'tmp_table' based on its results. I tried the following, but it's not working:
UPDATE tmp_table
SET count=Total
WHERE date=day AND hour=hour
FROM
(
select CONVERT(datetime, CONVERT(varchar, new_time, 101)) As day,
datepart(hh,new_time) As hour,count(*) As Total
from log_table
where new_time > GETDATE() - 180
group by CONVERT(datetime, CONVERT(varchar, new_time, 101)),datepart(dd,new_time),
datepart(hh,new_time)
order by CONVERT(datetime, CONVERT(varchar, new_time, 101)), datepart(hh,new_time))
)
I need to get the values "Total", "day" and "hour" from the subquery.
If you only want to update, then you don't need to order by and therefore you can use a CTE and a join as such:
With CTE AS
(
SELECT CONVERT(DATETIME, CONVERT(VARCHAR, new_time, 101)) As day,
DATEPART(hh,new_time) As hour,
COUNT(*) As Total
FROM log_table
WHERE new_time > GETDATE() - 180
GROUP BY CONVERT(DATETIME, CONVERT(VARCHAR, new_time, 101)),
DATEPART(dd,new_time),
DATEPART(hh,new_time)
)
UPDATE tmp_table
SET Count= CTE.Total
FROM tmp_table INNER JOIN CTE
ON temp_table.date=cte.day AND temp_table.hour=cte.hour

MS SQL distinct function

I have the query below
SELECT distinct
count(patient.id)
CAST(YEAR(completiondate) AS VARCHAR(4)) + '-' + CAST(MONTH(completiondate) AS VARCHAR(2)) AS Mjesec
FROM ....
WHERE
incident.completionDate Between Convert(smalldatetime, '01/10/2007', 103) and Convert(smalldatetime, '01/11/2013', 103)
and servicecharges.serviceid in (47)
and incident.status != 6
and ServiceRequestDescription LIKE 'something'
and chargeDescr = 'test'
group by CAST(YEAR(completiondate) AS VARCHAR(4)) + '-' + CAST(MONTH(completiondate) AS VARCHAR(2))
the result i take, have unique rows of patient.id AND Year-Month. That means that i can have multiple rows with the same patient.id and several year-month.
how can i change that query, in order to take the results, with each patient.id only once, with the first completiondate with the specific elements?
I guess it should be:
SELECT
patient.id
MIN(
CAST(YEAR(completiondate) AS VARCHAR(4)) + '-' + CAST(MONTH(completiondate) AS VARCHAR(2))
)
AS Mjesec
FROM ....
WHERE
incident.completionDate Between Convert(smalldatetime, '01/10/2007', 103) and Convert(smalldatetime, '01/11/2013', 103)
and servicecharges.serviceid in (47)
and incident.status != 6
and ServiceRequestDescription LIKE 'something'
and chargeDescr = 'test'
group by patient.id
Please Try it
WITH CTE AS
(
SELECT *,RN=ROW_NUMBER() OVER (PARTITION BY patient ORDER BY patient DESC) FROM tablename
)
select * from CTE where RN>1

How to build this sql query

i want to find the records in sql
from say 25-08-2012 to 01-09-2012
and i want to group by date
here is my query
SELECT CONVERT(VARCHAR(10), date, 105) AS dt,
COUNT(id) AS cnt
FROM tablename
WHERE date BETWEEN CONVERT(DATETIME, '21-08-2012 00:00:00:000',103)
AND CONVERT(DATETIME, '01-09-2012 23:59:00:000' ,103)
GROUP BY CONVERT(VARCHAR(10), date, 105)
i am getting result as
dt cnt
01-09-2012 48
27-08-2012 1
28-08-2012 3
29-08-2012 11
30-08-2012 3
but expect it as
dt cnt
25-08-2012 0
26-08-2012 0
01-09-2012 48
27-08-2012 1
28-08-2012 3
29-08-2012 11
30-08-2012 3
How i can modify above query
i also tried with CASE but no luck
Many Thanks..
The reason you are missing these dates in result is that there's no data for them in your table, however, the following would insure you are getting all of the dates in specified range:
CREATE TABLE #tmp_dates ([date] datetime)
DECLARE #dt_start datetime, #dt_end datetime, #dt_dif int
SET #dt_start = CONVERT(DATETIME, '21-08-2012 00:00:00:000',103)
SET #dt_end = CONVERT(DATETIME, '01-09-2012 23:59:00:000' ,103)
SET #dt_dif = datediff(day,#dt_start,#dt_end)
WHILE #dt_dif >= 0 BEGIN
INSERT INTO #tmp_dates
SELECT dateadd(day,#dt_dif,#dt_start)
SET #dt_dif = #dt_dif - 1
END
SELECT CONVERT(VARCHAR(10), t2.[date], 101) AS dt, COUNT(t1.id) AS cnt
INTO #tmp_result
FROM tablename t1
RIGHT OUTER JOIN #tmp_dates t2
ON CONVERT(VARCHAR(10), t1.[date], 101) = CONVERT(VARCHAR(10), t2.[date], 101)
GROUP BY CONVERT(VARCHAR(10), t2.[date], 101)
ORDER BY CONVERT(DATETIME,CONVERT(VARCHAR(10), t2.[date], 101)) ASC /* DESC */
SELECT convert(VARCHAR(10),CONVERT(DATETIME,dt),105) as dt,cnt FROM #tmp_result
DROP TABLE #tmp_dates
DROP TABLE #tmp_result
Your query cannot be directly modified to return the data you want. To count the dates in question, there must be records in the target table actually having those dates; in your case, however, the dates are merely parameters in the query. As a result, there is no way to incorporate them into your result set.
You must create a secondary table that includes all the dates for which you want data, and then recharacterize your query as a left outer join from that date table to your target table. This will, in turn, give you the zero counts for the dates present in the "date" table, but absent from the target table.
How about using IsNull()? Let me know if this works.
SELECT CONVERT(VARCHAR(10), date, 105) AS dt,
ISNULL(COUNT(id),0) AS cnt
FROM tablename
WHERE date BETWEEN CONVERT(DATETIME, '21-08-2012 00:00:00:000',103)
AND CONVERT(DATETIME, '01-09-2012 23:59:00:000' ,103)
GROUP BY CONVERT(VARCHAR(10), date, 105)

How many Stored Procedures created everyday ( problem in converting Datetime )?

I make a query that return to me the count of Stored Procedure that created everyday as follow
SELECT convert(varchar, crdate, 103) as Date,Count(*) as Counter
FROM sysobjects
WHERE (xtype = 'p') AND (name NOT LIKE 'dt%')
Group by convert(varchar, crdate, 103)
and its already work but dates appear in string format that i can't order it such as below
01/03/2010 3
01/04/2008 4
01/05/2010 5
01/11/2008 1
01/12/2008 4
02/03/2008 1
02/03/2010 2
02/04/2008 4
02/05/2010 2
02/11/2008 2
02/11/2009 2
02/12/2008 4
03/01/2010 1
03/02/2010 2
03/03/2010 2
03/04/2008 2
03/04/2010 2
03/05/2008 1
03/05/2010 2
I want to make that in which date is in datetime format that i can make order by successfully, i tried convert(datetime, crdate, 103) but it show Full date
any idea of how to do ?
To get a sortable date you need year, then month, then date. use format "112".
SELECT convert(varchar, crdate, 112) as Date,Count(*) as Counter
FROM sysobjects
WHERE (xtype = 'p') AND (name NOT LIKE 'dt%')
Group by convert(varchar, crdate, 112)
order by Date
which gives this:
Date Counter
20040711 124
20040713 1
20040725 1
20040726 2
20040803 6
If you want to get the right sort order but a differently formatted date, then you can use a subquery like this.
select CONVERT(varchar, GroupDate, 103) Date, Counter
FROM (
SELECT MIN(crdate) as GroupDate,Count(*) as Counter
FROM sysobjects
WHERE (xtype = 'p') AND (name NOT LIKE 'dt%')
Group by convert(varchar, crdate, 112)
) A
order by GroupDate
which yields
Date Counter
11/07/2004 124
13/07/2004 1
25/07/2004 1
26/07/2004 2
03/08/2004 6
How about this:
select dt, COUNT(*) from
(
SELECT convert(datetime, convert(varchar, crdate, 112)) as dt
FROM sysobjects
WHERE (xtype = 'p') AND (name NOT LIKE 'dt%')
) DayOnly
group by dt
order by dt asc
SELECT DATEADD(day, DATEDIFF(day, 0, o.crdate), 0) [Date],
COUNT(*) [Counter]
FROM sys.sysobjects o
WHERE o.xtype = 'p' AND o.name NOT LIKE 'dt%'
GROUP BY DATEADD(day, DATEDIFF(day, 0, o.crdate), 0)