I m working on sql server and stucked with how can I get the desired output.
I have the below as the source table.
and I want the desired output as below.
Here is the Query to have source table.
DECLARE #Temp TABLE(Capacity INT,CDate DATE,Name NVARCHAR(100))
INSERT INTO #Temp VALUES (1,'4/14/2014','M24')
INSERT INTO #Temp VALUES (1,'4/15/2014','M22')
INSERT INTO #Temp VALUES (1,'4/14/2014','M24')
INSERT INTO #Temp VALUES (1,'4/15/2014',NULL)
INSERT INTO #Temp VALUES (2,'4/14/2014','F67')
INSERT INTO #Temp VALUES (2,'4/15/2014','F31')
INSERT INTO #Temp VALUES (3,'4/14/2014','M53')
SELECT * FROM #Temp
Can anyone help me, please.
You can use the PIVOT function to get the result but since you need to return multiple rows for each Capacity, you will want to use a windowing function like row_number() that will generate a unique sequence for each Capacity and CDate combination:
SELECT Capacity, [2014-04-14], [2014-04-15]
FROM
(
SELECT Capacity,
CDate,
Name,
row_number() over(partition by capacity, cdate
order by capacity) seq
FROM #Temp
) d
PIVOT
(
MAX(name)
FOR CDate IN ([2014-04-14], [2014-04-15])
) piv
ORDER BY Capacity;
See SQL Fiddle with Demo
Related
My stored procedure is populating different rows and I need it to populate a single row. I have tried adding in some where clauses but that breaks it. Any help is appreciated!
DELIMITER //
CREATE PROCEDURE Populate()
BEGIN
insert into log(NoEmp) (select count(empid) from emp);
insert into log(NoDept) (select count(deptid) from dept);
insert into log(LocReg1) (select count(regionid) from region where regionid=1);
insert into log(LocReg2) (select count(regionid) from region where regionid=2);
insert into log(LocReg3) (select count(regionid) from region where regionid=3);
insert into log(TotSales) (select sum(salesamt) from sales);
insert into log(AvgSaleMo) (select TotSales/(24) from log);
insert into log(AvgSaleYr) (select TotSales/(2) from log);
insert into log(logdate) (select NOW());
END //
DELIMITER ;
Every time you INSERT it creates a new row (unless you use the ON DUPLICATE KEY UPDATE clause).
If you want to insert a single row, use a single INSERT with multiple columns and values.
INSERT INTO log (NoEmp, NoDept, LocReg1, LocReg2, LocReg3, TotSales, AvgSaleMo, AvgSaleYr, logdate)
VALUES (
(select count(empid) from emp),
(select count(deptid) from dept),
(select count(regionid) from region where regionid=1),
(select count(regionid) from region where regionid=2),
(select count(regionid) from region where regionid=3),
(select sum(salesamt) from sales),
(select sum(salesamt)/(24) from sales),
(select sum(salesamt)/(2) from sales),
NOW()
);
I have a table name as 'records' field is 'dates', how to get missing dates in a table based on passing two dates like 2018-03-23,2018-03-30 using MySQL query
records :
id dates
------------
1 2018-03-23
2 2018-03-24
3 2018-03-27
4 2018-03-28
5 2018-03-30
Expected Result is missing dates: 25,26,29
Here's a SQL Server Solution
declare #date datetime=(Select min(date) from table)
declare #maxdate datetime = (Select max(date) from table)
while #date<=#maxdate
begin
if #date not in (Select date from table)
select #date
select #date=dateadd(dd, 1, #date)
end
Please check the example below:
CREATE TABLE #tmp (
my_date DATETIME
)
INSERT INTO #tmp (my_date) VALUES ('2016-01-01')
INSERT INTO #tmp (my_date) VALUES ('2016-01-02')
INSERT INTO #tmp (my_date) VALUES ('2016-01-04')
INSERT INTO #tmp (my_date) VALUES ('2016-01-05')
INSERT INTO #tmp (my_date) VALUES ('2016-01-07')
INSERT INTO #tmp (my_date) VALUES ('2016-01-08')
INSERT INTO #tmp (my_date) VALUES ('2016-01-10')
INSERT INTO #tmp (my_date) VALUES ('2016-01-11')
DECLARE #max_date DATETIME
SELECT #max_date = max(my_date) FROM #tmp
SELECT DATEADD(day,1,t1.my_date) as miss_date
FROM #tmp t1
LEFT JOIN #tmp t2 ON t1.my_date=DATEADD(day,-1,t2.my_date)
WHERE t2.my_date is null
AND t1.my_date<>#max_date
Also, please see: MySQL: Find Missing Dates Between a Date Range
I have an SQL table with one column of integer values and I would like to find the median of those values without any sorting. I first tried finding the numbers in the table that are greater than and less than each value:
SELECT DISTINCT d1.v,
(SELECT COUNT(d2.v)
FROM Values d2
WHERE d2.v > d1.v
) AS greater_than,
(SELECT COUNT(d2.v)
FROM Values d2
WHERE d2.v < d1.v
) AS less_than
FROM Values d1
I'm not sure how to proceed. I believe I want the values in the above table where greater_than and less_than are both equal to num_entries / 2, but that would only work for a table with an even number of entries. What's a good way to get the median from what I have above?
You could do it like this:
SELECT (MIN(v)+MAX(v))/2
FROM (
SELECT CASE WHEN
LEAST((SELECT COUNT(*) FROM tbl WHERE v <= d1.v),
(SELECT COUNT(*) FROM tbl WHERE v >= d1.v))
>= (SELECT COUNT(*)/2 FROM tbl)
THEN v
END as v
FROM tbl d1
) as sub
The inner query is guaranteed to return 1 or 2 distinct non-null values among potentially many null values. The non-null values may repeat, but by taking the minimum and maximum those two values can be used to calculate the median.
NB: Don't name your table Values: it is a reserved word.
Look for total numbers for greater than and less than self number that is equal to the total number of rows/2.
create table med(id integer);
insert into med(id) values(1);
insert into med(id) values(2);
insert into med(id) values(3);
insert into med(id) values(4);
insert into med(id) values(5);
insert into med(id) values(6);
select (MIN(count)+MAX(count))/2 from
(select case when (select count(*) from
med A where A.id<B.id)=(select count(*)/2 from med) OR
(select count(*) from med A where A.id>B.id)=(select count(*)/2
from med) then cast(B.id as float)end as count from med B) C;
?column?
----------
3.5
(1 row)
You need cast to convert to float, otherwise you would get 3 here.
I create a temporary table #tbl(account, last_update). I have following two inserts from different source (could be tables from different databases) to insert account with last update date. For example
create table #tbl ([account] numeric(18, 0), [last_update] datetime)
insert into #tbl(account , last_update)
select table1.account, max(table1.last_update)
from table1 join…
group by table1.account
insert into #tbl(account , last_update)
select table2.account, max(table2.last_update)
from table2 join…
group by table2.account
The problem is this could cause duplicate account in the table #tbl. I either have to avoid it during each insert or remove the duplicate after both insert. Also, if there is account with two different last_update, I want the #tbl have the latest last_update. How do I achieve this conditional insert? Which one will have better performance?
Do you think you could rewrite your query to something like:
create table #tbl ([account] numeric(18, 0), [last_update] datetime)
insert into #tbl(account , last_update)
select theaccount, MAX(theupdate) from
(
select table1.account AS theaccount, table1.last_update AS theupdate
from table1 join…
UNION ALL
select table2.account AS theaccount, table2.last_update AS theupdate
from table2 join…
) AS tmp GROUP BY theaccount
The UNION ALL will build you 1 unique table combining table1 + table2 records. From there, you can act as if was a regular table, which means that you are able to find the max last_update for each record using a "group by"
insert into #tbl(account , last_update)
select account, last_update
from
(
select a.* from #table1 a where
last_update in( select top 1 last_update from #table1 b
where
a.account = b.account
order by last_update desc)
UNION
select a.* from #table2 a where
last_update in( select top 1 last_update from #table2 b
where
a.account = b.account
order by last_update desc)
) AS tmp
Let suppose my table can have values from 000 to 999 (three digits and less than 1000)
Some of this values are filled. Let's suppose currently my table has
000,002,005,190 (001,004,003,006,..189,191,..,999 can be inserted into table)
and these values are randomly allocated 000 and 002 is in table but 001 is not in table yet.
How can I get the values that I can insert into table yet.
DECLARE #t TABLE
(VALUE CHAR(3))
INSERT #t
VALUES
('000'),('002'),('005'),('190')
;WITH rnCTE
AS
(
SELECT -1 + ROW_NUMBER() OVER (ORDER BY TYPE, number, name) AS rn
FROM master.dbo.spt_values
)
SELECT RIGHT('000' + CAST( rn AS VARCHAR(11)),3)
FROM rnCTE
WHERE NOT EXISTS ( SELECT 1 FROM #t
WHERE VALUE = rn
)
AND rn < 1000
EDIT
This query works by generating the complete list of possible numbers from a system table (master.dbo.spt_values) which is guaranteed to contain more than 1000 rows inside the CTE rnCTE. -1 is added to ROW_NUMBER to have the values start at 0 rather than 1.
The outer query zero pads the numbers for display, returning only those which are not in the source data and are less than 1000.
DECLARE #t TABLE(id INT)
INSERT INTO #t (id)
VALUES
(1),(19),(3)
;WITH numbers AS (
SELECT ROW_NUMBER() OVER(ORDER BY o.object_id,o2.object_id) RN FROM sys.objects o
CROSS JOIN sys.objects o2
), NotExisted AS(
SELECT * FROM numbers WHERE RN NOT IN (SELECT ID FROM #t)
AND RN<1000)
SELECT TOP 1 RN FROM NotExisted ORDER BY NEWID()
You will have to write a T-SQL to first query and find the gaps. There is no ready made SQL that will give you the gaps directly.