How to display null value instead of numeric - sql

Using SQL Server 2008
table1
id name
001 rahim
002 vijay
table2
id name amount
003 vijayan 08.00
004 suresh 12.00
I want to combine table1 & table2 using union
Query
Select id, name, '' from table1 union Select id, name amount from table2
Output
id name amount
001 rahim 0 -- 0 should not appear, should be null
002 vijay 0 -- 0 should not apperar, should be null
003 vijayan 08.00
004 suresh 12.00
0 is display instead of null, because of table2 amount column is numeric.
How to handle this. Need SQL Query help

select id, name, amount from table2
union all
select id, name, null from table1
order by id

As per Microsoft's msdn site regarding the UNION operator link: msdn UNION
The number and order of columns must match and be type compatible.
User: podiluska uses the correct approach.

Related

Getting records from 2 tables with common an uncommon columns

Below is similar example of the issue I have:
if I have this table 1:
Patient ID
Name
Check in Date
order name
preformed by
1
Jack
12/sep/2002
xray
Dr.Amal
2
Nora
15/oct/2002
ultrasound
Dr.Goerge
1
Jack
13/nov/2003
Medicine
Dr.Fred
table 2:
Patient ID
Name
Check in Date
order name
1
Jack
14/Jun/2002
xray 2
2
Nora
15/oct/2002
ultrasound
1
Jack
13/nov/2003
Medicine
3
Rafael
13/nov/2003
Vaccine
The result I need is as the following:
Name
Check in Date
order name
preformed by
Jack
12/sep/2002
xray
Dr.Amal
Nora
15/oct/2002
ultrasound
Dr.Goerge
Jack
13/nov/2003
Medicine
Dr.Fred
Jack
14/Jun/2002
xray 2
Null
Rafael
13/nov/2003
Vaccine
Null
If you noticed the result I need is all records of table 1 and all records of table 2 with no duplication and joining the same common fields and adding 'Preformed by' column from Table 1. I tried using 'UNION' as the following:
SELECT Name, Check_in_Date, order_name,preformed_by
FROM table1
UNION
SELECT Name, Check_in_Date, order_name,''
FROM table2
the result I get is 2 records for each patient with the same date one with preformed by one with null as the following:
Name
Check in Date
order name
preformed by
Jack
12/sep/2002
xray
Dr.Amal
Nora
15/oct/2002
ultrasound
Dr.Goerge
Nora
15/oct/2002
ultrasound
Null
Jack
13/nov/2003
Medicine
Dr.Fred
Jack
13/nov/2003
Medicine
null
Jack
14/Jun/2002
xray 2
Null
Rafael
13/nov/2003
Vaccine
Null
If the same ID has same check in date in both table it must return the preformed by of table 1 not null How can I do this?
Thank you.
What you need is a FULL JOIN matching by those three columns along with NVL() function in order to bring the values
from table2 which return null from table1 such as
SELECT NVL(t1.name,t2.name) AS name,
NVL(t1.check_in_date,t2.check_in_date) AS check_in_date,
NVL(t1.order_name,t2.order_name) AS order_name,
t1.preformed_by
FROM table1 t1
FULL JOIN table2 t2
ON t1.name = t2.name
AND t1.check_in_date = t2.check_in_date
AND t1.order_name = t2.order_name
or another method uses UNION to filter out duplicates and then applies an OUTER JOIN such as
SELECT tt.name, tt.check_in_date, tt.order_name, t1.preformed_by
FROM (
SELECT name, check_in_date, order_name FROM table1 UNION
SELECT name, check_in_date, order_name FROM table2
) tt
LEFT JOIN table1 t1
ON t1.name = tt.name
AND t1.check_in_date = tt.check_in_date
AND t1.order_name = tt.order_name
Demo

Store row values as new column before group by

Anyone know how I can group by, but keep a distinct column? I messed around with UNPIVOT but couldnt find a good explanation to help me write my code. Anyone have a solution?
I have data that looks like this:
acct contact email phone
1 44 abc NULL
1 33 NULL 123
2 2 xxx NULL
2 22 NULL 456
I use
select acct,max(email) as email, max(phone) as phone from my_table
group by acct
to wind up with this:
acct email phone
1 abc 123
2 xxx 456
but my end goal is to group by and create a separate contact column for phone and email like this:
acct contact_email email phone contact_phone
1 44 abc 123 33
2 2 xxx 456 22
You appears to want simple aggregation :
select acct,
max(case when phone is null then contact end) as contact_email,
max(email) as email, max(phone) as phone,
max(case when email is null then contact end) as contact_phone
from table t
group by acct;
Try Below, might be it will help, without sub query and without group
SELECT t1.acct,t1.contact contact_email,t1.email, t2.phone,t2.contact contact_phone FROM my_table t1 inner join my_table t2 on t1.acct=t2.acct
where t1.email is not null and t2.phone is not null

SQL: Adding new column to show count of ID by date

I am hoping someone can help me with my query.
I have a table with the columns, 'Date', 'ID_Num and 'Name'. What I want to do is add a column at the end to show the total amount of times each ID_Num is within the data but based on the date. So although 'ID_Num' 1001 shows 4 times in total, it is twice on the 20/04/2018 and once on both the 21/04/2018 and 22/04/2018.
EDIT: I should have stipulated that I will be pulling several other columns with information, which I cant use a group by on everything.
Date ID_Num Name Count
20/04/2018 1001 John 2
20/04/2018 1001 John 2
20/04/2018 1002 Paul 2
20/04/2018 1002 Paul 2
20/04/2018 1003 David 2
20/04/2018 1003 David 2
20/04/2018 1004 Stephen 1
21/04/2018 1001 John 1
21/04/2018 1002 Paul 3
21/04/2018 1002 Paul 3
21/04/2018 1002 Paul 3
21/04/2018 1004 Stephen 1
22/04/2018 1001 John 1
22/04/2018 1002 Paul 1
22/04/2018 1003 David 1
22/04/2018 1004 Stephen 1
Thanks
Unless I'm missing something here, a simple group by and count should do it:
SELECT Date, ID_Num, Name, Count(*)
FROM TableName
GROUP BY Date, ID_Num, Name
(That is, assuming there can only be one Name for each ID_Num)
Update
Assuming your rdbms supports it, you can use count with an over clause:
SELECT Date, ID_Num, Name, Count(*) OVER(PARTITION BY Date, Id_Num)
FROM TableName
If not, you can use a sub query:
SELECT Date,
ID_Num,
Name,
(SELECT Count(*)
FROM TableName As t1
WHERE t1.Date = t0.Date
AND t1.ID_NUM = t0.ID_NUM)
FROM TableName As t0
Try this:
SELECT
Date,
Id_num,
count(*) count
FROM
tabel_name
GROUP BY
Date,
Id_num
If you want name as well:
SELECT
Date,
Id_num,
Name
count(*) count
FROM
tabel_name
GROUP BY
Date,
Id_num,
Name
You can use a normal select query and then add a sub query to do a group and show the total. Simple example below
SELECT Date, ID_Num, Name,
(SELECT Count(ID_Num) FROM TableName AS CHILD WHERE CHILD.Id_Num = Parent.Id_Num) AS Total
FROM TableName AS Parent

SQL Server: join 3 tables and sum() one column from each table

I have 3 tables
-----------table1-------------
id code name quantity
1 001 car1 1
2 002 car2 2
3 003 car3 3
-----------table2-------------
id code name quantity
1 001 car1 1
2 002 car2 2
-----------table3-------------
id code name quantity
1 001 car1 1
2 002 car2 2
3 004 car4 4
I want to join the three tables and take the total from quantity in SQL Server:
---------table-------
code name total
001 car1 3
002 car2 6
003 car3 3
004 car4 4
In MySql I try this and worked, but in SQL Server, I get me error :(
select
ID, CODE, NAME, sum(QUANTITY) as total
from
(select ID, CODE, NAME, QUANTITY from AP1
union all
select ID, CODE, NAME, QUANTITY from AP2
union all
select ID, CODE, NAME, QUANTITY from AP3) x
group by ID;
Your method would work in any database, if your group by fields match the unaggregated columns:
select CODE, NAME, sum(QUANTITY) as total
from (select ID, CODE, NAME, QUANTITY from AP1 union all
select ID, CODE, NAME, QUANTITY from AP2 union all
select ID, CODE, NAME, QUANTITY from AP3
) x
group by CODE, NAME;
The fact that it works in MySQL is due to a (mis)feature that allows any unaggregated columns in the select for an aggregation query. In general, other databases do not support this non-standard syntax.

Select Most Recent Entry in SQL

I'm trying to select the most recent non zero entry from my data set in SQL. Most examples of this are satisfied with returning only the date and the group by variables, but I would also like to return the relevant Value. For example:
ID Date Value
----------------------------
001 2014-10-01 32
001 2014-10-05 10
001 2014-10-17 0
002 2014-10-03 17
002 2014-10-20 60
003 2014-09-30 90
003 2014-10-10 7
004 2014-10-06 150
005 2014-10-17 0
005 2014-10-18 9
Using
SELECT ID, MAX(Date) AS MDate FROM Table WHERE Value > 0 GROUP BY ID
Returns:
ID Date
-------------------
001 2014-10-05
002 2014-10-20
003 2014-10-10
004 2014-10-06
005 2014-10-18
But whenever I try to include Value as one of the selected variables, SQLServer results in an error:
"Column 'Value' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause."
My desired result would be:
ID Date Value
----------------------------
001 2014-10-05 10
002 2014-10-20 60
003 2014-10-10 7
004 2014-10-06 150
005 2014-10-18 9
One solution I have thought of would be to look up the results back in the original Table and return the Value that corresponds to the relevant ID & Date (I have already trimmed down and so I know these are unique), but this seems to me like a messy solution. Any help on this would be appreciated.
NOTE: I do not want to group by Value as this is the result I am trying to pull out in the end (i.e. for each ID, I want the most recent Value). Further Example:
ID Date Value
----------------------------
001 2014-10-05 10
001 2014-10-06 10
001 2014-10-10 10
001 2014-10-12 8
001 2014-10-18 0
Here, I only want the last non zero entry. (001, 2014-10-12, 8)
SELECT ID, MAX(Date) AS MDate, Value FROM Table WHERE Value > 0 GROUP BY ID, Value
Would return:
ID Date Value
----------------------------
001 2014-10-10 10
001 2014-10-12 8
This can also be done using a window function which is very ofter faster than a join on a grouped query:
select id, date, value
from (
select id,
date,
value,
row_number() over (partition by id order by date desc) as rn
from the_table
) t
where rn = 1
order by id;
Assuming you don't have repeated dates for the same ID in the table, this should work:
SELECT A.ID, A.Date, A.Value
FROM
T1 AS A
INNER JOIN (SELECT ID,MAX(Date) AS Date FROM T1 WHERE Value > 0 GROUP BY ID) AS B
ON A.ID = B.ID AND A.Date = B.Date
select a.id, a.date, a.value from Table1 a inner join (
select id, max(date) mydate from table1
where Value>0 group by ID) b on a.ID=b.ID and a.Date=b.mydate
Using Subqry,
SELECT ID, Date AS MDate, VALUE
FROM table t1
where date = (Select max(date)
from table t2
where Value >0
and t1.id = t2.id
)
Answers provided are perfectly adequate, but Using CTE:
;WITH cteTable
AS
(
SELECT
Table.ID [ID], MAX(Date) [MaxDate]
FROM
Table
WHERE
Table.Value > 0
GROUP BY
Table.ID
)
SELECT
cteTable.ID, cteTable.Date, Table.Value
FROM
Table INNER JOIN cteTable ON (Table.ID = cteTable.ID)