SQL Simple Join and I'm stumped - sql

I have a table with columns:
JOB_NUM, HM_PH, BUS_PH, CALL1ST
Where the job_num is a unique number
And the HM_PH, BUS_PH, and CALL1ST columns are 10 digit phone numbers
So using the order of columns above, sample data would look like:
JOB_NUM, HM_PH, BUS_PH, CALL1ST
------------------------------------
12345, 4025557848, 9165897588, 7518884455
10101, 8887776655, 8667416895, 5558884446
What I want to produce is 2 columns.
JOB_NUM, PHONE
Where the job_num is listed next to every phone number such as:
JOB_NUM PHONE
---------------------
12345 4025557848
12345 9165897588
12345 7518884455
10101 8887776655
10101 8667416895
10101 5558884446
Where do I start?

You need a UNION (if you want to remove duplicate rows) or UNION ALL (if you want to keep duplicate rows):
SELECT JOB_NUM, HM_PH AS PHONE FROM yourtable
UNION
SELECT JOB_NUM, BUS_PH FROM yourtable
UNION
SELECT JOB_NUM, CALL1ST FROM yourtable
ORDER BY JOB_NUM

Make a UNION ALL for all numbers you need (with duplicates) or UNION when you need unique rows:
select JOB_NUM,HM_PH AS PHONE
from YourTableName
union all
select JOB_NUM,BUS_PH AS PHONE
from YourTableName
union all
select JOB_NUM,CALL1ST_PH AS PHONE
from YourTableName

create table yourtable
(
id int,
HM_PH nvarchar(10),
BUS_PH nvarchar(10),
CALL1ST nvarchar(10)
)
insert into yourtable
select 12345, 4025557848, 9165897588, 7518884455
union
select 10101, 8887776655, 8667416895, 5558884446
select * from yourtable
select ID,p.Phone
from temptemp
unpivot( Phone for phoneCol in (HM_PH,BUS_PH,CALL1ST)) p
order by id
drop table yourtable

Related

How to ROWCOUNT_BIG() value with union all

I have the following query in SQL Server. How do I get the number of rows of previous select query as following format?
Sample Query
select ID, Name FROM Branch
UNION ALL
SELECT ROWCOUNT_BIG(), ''
Sample Output
If you use a CTE you can count the rows and union all together:
with cte as (
select ID, [Name]
from dbo.Branch
)
select ID, [Name]
from cte
union all
select count(*) + 1, ''
from cte;
I think you want to see total count of the select statement. you can do this way.
CREATE TABLE #test (id int)
insert into #test(id)
SELECT 1
SELECT id from #test
union all
SELECT rowcount_big()
Note: Here, the ID will be implicitly converted to BIGINT datatype, based on the datatype precedence. Read more
Presumably, you are running this in some sort of application. So why not use ##ROWCOUNT?
select id, name
from . . .;
select ##rowcount_big; -- big if you want a bigint
I don't see value to including the value in the same query. However, if the underlying query is an aggregation query, there might be a way to do this using GROUPING SETS.
Here are two ways. It's better to use a CTE to define the row set so further table inserts don't interfere with the count. Since you're using ROWCOUNT_BIG() these queries use COUNT_BIG() (which also returns bigint) to count the inserted rows. In order to make sure the total always appears as the last row an 'order_num' column was added to the SELECT list and ORDER BY clause.
drop table if exists #tTest;
go
create table #tTest(
ID int not null,
[Name] varchar(10) not null);
insert into #tTest values
(115, 'Joe'),
(116, 'Jon'),
(117, 'Ron');
/* better to use a CTE to define the row set */
with t_cte as (
select *
from #tTest)
select 1 as order_num, ID, [Name]
from t_cte
union all
select 2 as order_num, count_big(*), ''
from t_cte
order by order_num, ID;
/* 2 separate queries could give inconsistent result if table is inserted into */
select 1 as order_num, ID, [Name]
from #tTest
union all
select 2 as order_num, count_big(*), ''
from #tTest
order by order_num, ID;
Both return
order_num ID Name
1 115 Joe
1 116 Jon
1 117 Ron
2 3

SQL - How to Order By in UNION query

Is there a way to union two tables, but keep the rows from the first table appearing first in the result set? However orderby column is not in select query
For example:
Table 1
name surname
-------------------
John Doe
Bob Marley
Ras Tafari
Table 2
name surname
------------------
Lucky Dube
Abby Arnold
Result
Expected Result:
name surname
-------------------
John Doe
Bob Marley
Ras Tafari
Lucky Dube
Abby Arnold
I am bringing Data by following query
SELECT name,surname FROM TABLE 1 ORDER BY ID
UNION
SELECT name,surname FROM TABLE 2
The above query is not keeping track of order by after union.
P.S - I dont want to show ID in my select query
I am getting ORDER BY Column by joining tables. Following is my real query
SELECT tbl_Event_Type_Sort_Orders.Appraisal_Event_Type_ID AS Appraisal_Event_Type_ID , ISNULL(tbl_Appraisal_Event_Types.Appraisal_Event_Type_Display_Name, 'UnCategorized') AS Appraisal_Event_Type_Display_Name
INTO #temptbl
FROM tbl_Event_Type_Sort_Orders
INNER JOIN tbl_Appraisal_Event_Types
ON tbl_Event_Type_Sort_Orders.Appraisal_Event_Type_ID = tbl_Appraisal_Event_Types.Appraisal_Event_Type_ID
WHERE 1=1
AND User_Name='abc'
ORDER BY tbl_Event_Type_Sort_Orders.Sort_Order
SELECT * FROM #temptbl
UNION
SELECT DISTINCT (tbl_Appraisal_Event_Types.Appraisal_Event_Type_ID) AS Appraisal_Event_Type_ID , ISNULL(tbl_Appraisal_Event_Types.Appraisal_Event_Type_Display_Name, 'UnCategorized') AS Appraisal_Event_Type_Display_Name
FROM tbl_Appraisal_Event_Types
INNER JOIN tbl_Appraisal_Events
ON tbl_Appraisal_Event_Types.Appraisal_Event_Type_ID = tbl_Appraisal_Events.Event_Type_ID
INNER JOIN tbl_Appraisals
ON tbl_Appraisal_Events.Appraisal_ID = tbl_Appraisal_Events.Appraisal_ID
WHERE 1=1
AND ((tbl_Appraisals.Assigned_To_Staff_User) = 'abc' OR (tbl_Appraisals.Assigned_To_Staff_User2) = 'abc' OR (tbl_Appraisals.Assigned_To_Staff_User3) = 'abc')
Put a UNION ALL in a derived table. To keep duplicate elimination, do select distinct and also add a NOT EXISTS to second select to avoid returning same person twice if found in both tables:
select name, surname
from
(
select distinct name, surname, 1 as tno
from table1
union all
select distinct name, surname, 2 as tno
from table2 t2
where not exists (select * from table1 t1
where t2.name = t1.name
and t2.surname = t1.surname)
) dt
order by tno, surname, name
You can use a column for the table and one for the ID to order by:
SELECT x.name, x.surname FROM (
SELECT ID, TableID = 1, name, surname
FROM table1
UNION ALL
SELECT ID = -1, TableID = 2, name, surname
FROM table2
) x
ORDER BY x.TableID, x.ID
You can write as below, if you are ok with duplicate data then please use UNION ALL it will be faster:
SELECT NAME, surname FROM (
SELECT ID,name,surname FROM TABLE 1
UNION
SELECT ID,name,surname FROM TABLE 2 ) t ORDER BY ID
this will order the first row sets first then by anything you need
(haven't tested the code)
;with cte_1
as
(SELECT ID,name,surname,1 as table_id FROM TABLE 1
UNION
SELECT ID,name,surname,2 as table_id FROM TABLE 2 )
SELECT name, surname
FROM cte_1
ORDER BY table_id,ID
simply use a UNION clause with out order by.
SELECT name,surname FROM TABLE 1
UNION
SELECT name,surname FROM TABLE 2
if you wanted to order first table use the below query.
;WITH cte_1
AS
(SELECT name,surname,ROW_NUMBER()OVER(ORDER BY Id)b FROM TABLE 1 )
SELECT name,surname
FROM cte_1
UNION
SELECT name,surname
FROM TABLE 2

Select multi identity values for multiple inserts along with columns not inserted into the table

I am inserting only 1 column into TempId table i.e name from a select statement
How do i get corresponding orderId for the identity column.
INSERT INTO tempId
output inserted.ID
Select name FROM (
select 'erty' as name, 1 as orderid union
select 'rth' as name, 2 as orderid union
select 'yt' as name, 3 as orderid union
select '345' as name, 4 as orderid union
select 'rtyu' as name, 5 as orderid union
select 'uio' as name, 6 as orderid union
select 'yu' as name, 7 as orderid union
select 'xzf' as name, 8 as orderid
) as a
PS Note: SELECT with union is only done for sample query. Ideally I will get things from another table.
You put the id and any other fields you need to use later in a table varaiable or temp table by using the OUTPUT clause
DECLARE #MyTableVar table( ID int, orderid int);
INSERT mytable (field1, orderID)
OUTPUT INSERTED.ID, INSERTED.OrderID
INTO #MyTableVar
SELECT FIELD2, orderid FROM Myothertable
Now you have the data available in #MyTableVar to do inserts to child tables or the other work you wanted to do.
just arrange the columns:
create table #tempID( id int, name varchar(50))
INSERT INTO #tempID (name, id)
output inserted.ID
Select name, orderid FROM (
select 'erty' as name, 1 as orderid union
select 'rth' as name, 2 as orderid union
select 'yt' as name, 3 as orderid union
select '345' as name, 4 as orderid union
select 'rtyu' as name, 5 as orderid union
select 'uio' as name, 6 as orderid union
select 'yu' as name, 7 as orderid union
select 'xzf' as name, 8 as orderid
) as a
This is an example on inserting values directly. If there are no triggers you can get ##IDENTITY.
insert into [FTSwordDef] ([word]) values ('value')
select scope_identity();
Scope_identity (and the evil ##) will only return the last iden. If you are inserting multiple rows then I think you would need to loop in a SP and build up the list of iden. Iden is created by the insert and is not available IN the insert to my knowledge.
If you held a tablock on the the insert and retrieved the last identity and how many rows were inserted then in theory the insert got the last x inden values. If your insert was sorted you would know what iden went with which row.

SQL - order by list order

I have the following query that returns rows based on a comma seperated list
Select * from Table where RecordID in (22,15,105,1,65,32)
I would like the results of this query to return to in the order of the ID's in the list. Is that possible with SQL?
Thanks in advance
select * from Table
where RecordID in (22,15,105,1,65,32)
order by (
case RecordID
when 22 then 1
when 15 then 2
when 105 then 3
when 1 then 4
when 65 then 5
when 32 then 6 end)
If you need the output to appear in a particular order, then you need to specify that order, using something the server can sort. Not knowing which engine you're working against, the general scheme would be to create a temp table or use rowset constructors to pair each record ID with its desired sort order.
E.g. (SQL Server)
declare #T table (RecordID int,Position int)
insert into #T (RecordID,Position)
select 22,1 union all
select 15,2 union all
select 105,3 union all
select 1,4 union all
select 65,5 union all
select 32,6
select * from Table t inner join #T t2 on t.RecordID = t2.RecordID order by t2.Position
I'd to the ordering in the client, but if you really want to do it in SQL, do it like this:
declare #T table (id int identity(1,1), RecordID int)
insert into #T (RecordID)
values (22), (15), (105), (1), (65), (32)
select * from
[table] t
inner join #t s on t.id=s.recordid
where t.id in (22, 15, 105, 1, 65, 32)
order by s.id
(works in SQL Server 2008)
Yes. You add the ORDER BY recordedid clause at the end.
The last time I had to do this I ended up doing a union all and generating a select statement for each id, i.e.
select * from Table where RecordID = 22
union all
select * from table where recordid = 15
etc.
It was a pain but it worked.
Use ORDER BY against the RecordID
Select * from Table where RecordID in (22,15,105,1,65,32) ORDER BY RecordID

SQL - Getting Most Recent Date From Multiple Columns

Assume a rowset containing the following
EntryID Name DateModified DateDeleted
-----------------------------------------------
1 Name1 1/2/2003 NULL
2 Name1 1/3/2005 1/5/2008
3 Name1 1/3/2006 NULL
4 Name1 NULL NULL
5 Name1 3/5/2008 NULL
Clarification:
I need a single value - the largest non-null date from BOTH columns. So the largest of all ten cells in this case.
SELECT MAX(CASE WHEN (DateDeleted IS NULL OR DateModified > DateDeleted)
THEN DateModified ELSE DateDeleted END) AS MaxDate
FROM Table
For MySQL, Postgres or Oracle, use the GREATEST function:
SELECT GREATEST(ISNULL(t.datemodified, '1900-01-01 00:00:00'),
ISNULL(t.datedeleted, '1900-01-01 00:00:00'))
FROM TABLE t
Both Oracle and MySQL will return NULL if a NULL is provided. The example uses MySQL null handling - update accordingly for the appropriate database.
A database agnostic alternative is:
SELECT z.entryid,
MAX(z.dt)
FROM (SELECT x.entryid,
x.datemodified AS dt
FROM TABLE x
UNION ALL
SELECT y.entryid
y.datedeleted AS dt
FROM TABLE y) z
GROUP BY z.entryid
As a general solution, you could try something like this:
select max(date_col)
from(
select max(date_col1) AS date_col from some_table
union
select max(date_col2) AS date_col from some_table
union
select max(date_col3) AS date_col from some_table
...
)
There might be easier ways, depending on what database you're using.
How about;
SELECT MAX(MX) FROM (
SELECT MAX(DateModified) AS MX FROM Tbl
UNION
SELECT MAX(DateDeleted) FROM Tbl
) T
The answer depends on what you really want. If you simply want the most recent of the two date values then you can do:
Select Max(DateModified), Max(DateDeleted)
From Table
If you are asking for the largest value from either column, then you can simply do:
Select Case
When Max(DateModified) > Max(DateDeleted) Then Max(DateModified)
Else Max(DateDeleted)
End As MaxOfEitherValue
From Table
The above are all valid answers;
But I'm Not sure if this would work?
select IsNull((
select MAX(DateModified)
from table
)
,
(
select MAX(DateDeleted)
from table
)
) as MaxOfEitherValue
from table
Edit 1:
Whilst in the shower this morning, I had another solution:
Solution 2:
select MAX(v) from (
select MAX(DateModified) as v from table
union all
select MAX(DateDeleted) as v from table
) as SubTable
Edit 3:
Damn it, just spotted this is the same solution as Alex k. sigh...
How to find the Latest Date from the columns from Multiple tables
e.g. if the Firstname is in Table1, Address is in Table2, Phone is in Table3:
When you are using with main SELECT statement while selecting other columns it is best written as :
SELECT Firstname
,Lastname
,Address
,PhoneNumber
,
,(SELECT max(T.date_col) from(select max(date_col1) AS date_col from Table1 Where ..
union
select max(date_col2) AS date_col from Table2 Where..
union
select max(date_col3) AS date_col from Table3 Where..
) AS T
) AS Last_Updated_Date
FROM Table T1
LEFT JOIN Table T2 ON T1.Common_Column=T2.Common_Column
LEFTJOIN Table T3 ON T1.Common_Column=T3.Common_Column