I'm able to run the next sql script once, to insert some rows using information from 2 unrelated tables :
INSERT INTO CompanyCarType (Name, CompanyId, LastModDateTime, LastModUserId)
SELECT T.Name, C.Id , GETDATE() LastModDateTime, C.LastModUserId
FROM CarType T
CROSS JOIN Company C
But, I need to be able to run this script many times without inserting duplicates, or failing in my case, as the table won't allow duplicated CompanyId
and Name.
So I tried to use WHERE NOT EXISTS, but as there are 2 tables in the SELECT statement, I can't use an alias to refer to it, and the syntax is incorrect.
INSERT INTO CompanyCarType (Name, CompanyId, LastModDateTime, LastModUserId)
SELECT T.Name, C.Id , GETDATE() LastModDateTime, C.LastModUserId
FROM CarType T
CROSS JOIN Company C) AS T1
WHERE NOT EXISTS (SELECT Name
FROM CompanyCarType T2
WHERE T2.Name = T1.Name)
There are a lot of goof examples out there using one table on the SELECT clause, but none then with 2 or more tables.
Thanks!
You can make use of rownumber while doing insert and then add Company ID in the where not exists clause.
INSERT INTO CompanyCarType
(Name, CompanyId, LastModDateTime, LastModUserId)
SELECT T.Name, C.Id , GETDATE() LastModDateTime, C.LastModUserId, ROW_NUMBER() over (partition by t.name, c.ID order by LastModDateTime) rownum
FROM CarType T CROSS JOIN Company C) as T1
WHERE t1.rownum = 1 and NOT EXISTS(SELECT Name
FROM CompanyCarType T2
WHERE T2.Name = T1.Name and t2.CompanyId = t1.ID)
Related
I have following result set,
Now with above results i want to print the records via select query as below attached image
Please note, I will have only two types of columns in output Present Employee & Absent Employees.
I tried using pivot tables, temporary table but cant achieve what I want.
One method would be to ROW_NUMBER each the the "statuses" and then use a FULL OUTER JOIN to get the 2 datasets into the appropriate columns. I use a FULL OUTER JOIN as I assume you could have a different amount of employees who were present/absent.
CREATE TABLE dbo.YourTable (Name varchar(10), --Using a name that doesn't require delimit identification
Status varchar(7), --Using a name that doesn't require delimit identification
Days int);
GO
INSERT INTO dbo.YourTable(Name, Status, Days)
VALUES('Mal','Present',30),
('Jess','Present',20),
('Rick','Absent',30),
('Jerry','Absent',10);
GO
WITH RNs AS(
SELECT Name,
Status,
Days,
ROW_NUMBER() OVER (PARTITION BY Status ORDER BY Days DESC) AS RN
FROM dbo.YourTable)
SELECT P.Name AS PresentName,
P.Days AS PresentDays,
A.Name AS AbsentName,
A.Days AS AbsentDays
FROM (SELECT R.Name,
R.Days,
R.Status,
R.RN
FROM RNs R
WHERE R.Status = 'Present') P
FULL OUTER JOIN (SELECT R.Name,
R.Days,
R.Status,
R.RN
FROM RNs R
WHERE R.Status = 'Absent') A ON P.RN = A.RN;
GO
DROP TABLE dbo.YourTable;
db<>fiddle
2 CTE's is actually far neater:
WITH Absents AS(
SELECT Name,
Status,
Days,
ROW_NUMBER() OVER (ORDER BY Days DESC) AS RN
FROM dbo.YourTable
WHERE Status = 'Absent'),
Presents AS(
SELECT Name,
Status,
Days,
ROW_NUMBER() OVER (ORDER BY Days DESC) AS RN
FROM dbo.YourTable
WHERE Status = 'Present')
SELECT P.Name AS PresentName,
P.Days AS PresentDays,
A.Name AS AbsentName,
A.Days AS AbsentDays
FROM Absents A
FULL OUTER JOIN Presents P ON A.RN = P.RN;
I have the following code:
IF (OBJECT_ID('tempdb..#Data') IS NOT NULL)
BEGIN
DROP TABLE #Data
END
SELECT
t.Name, x.Time, x.Date, x.Total,
xo.DrvCommTotal, x.Name2, x.Street, x.Zip,
r.Route1
INTO
#Data
FROM
table1 xo WITH(NOLOCK)
LEFT JOIN
Table2 t WITH(NOLOCK) ON t.ID = x.ID
LEFT JOIN
Route1 r ON r.RouteID = x.RouteID
WHERE
x.Client = 1
AND x.Date = '9/13/2018'
GROUP BY
t.Name, x.Time, x.Date, x.Total, xo.DrvCommTotal, x.Name2,
x.Street, x.Zip, r.Route1
ORDER BY
Route1
SELECT DISTINCT
F.*, F2.NumOrders
FROM
#Data F
LEFT JOIN
(SELECT
Route1, COUNT(*) NumOrders
FROM
#Data
GROUP BY
Route1) F2 ON F2.Route1 = F.Route1
LEFT OUTER JOIN
(SELECT
Street + ',' + Zip Stops, Time, RouteN1
FROM
#Data
GROUP BY
RouteNo1, street, Zip) F3 ON F3.Route1 = F.Route1
WHERE
F.Route1 IS NOT NULL
ORDER BY
F.Route1
and it provides me with a list of routes and stops. The column NumOrders lets me know how many orders are on each route. I need the stops to become individual columns I will label Stop1, Stop2, etc. so that each route is only one row and all the information is contained on the row for one route.
I'm currently using the temp table because the data is so large. I can play with my SELECT statement without having to re-run the entire code.
How do I move the stops for each route into columns?
Hum.. Not quite sure I understand the question but it sounds that you want to pivot the data so that the routes break into columns. If so, I would use a sql Pivot. Here is an example from the documentation:
USE AdventureWorks2014;
GO
SELECT VendorID, [250] AS Emp1, [251] AS Emp2, [256] AS Emp3, [257] AS Emp4, [260] AS Emp5
FROM
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [250], [251], [256], [257], [260] )
) AS pvt
ORDER BY pvt.VendorID;
Also, here is the link to how to use pivot: https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-2017
Since you already have all the data in your temp table, you could pivot that on the way out.
I have the following tables:
MASTER table (ID(PK), NAME, etc)
DETAIL table (ID(PK), IDMASTER(FK), VALUE1, DATE1, etc)
What I need is a SQL query or a way to do a select like
I work with SQL Server.
What I need is a SQL query or a way to do a select like
SELECT
M.ID, M.NAME,
(SELECT TOP 1 DT.ID, DT.VALUE1
FROM DETAIL D
WHERE D.IDMASTER = M.ID
ORDER BY DATE 1 DESC)
-- more than one column with a where clause and an order clause
FROM
MASTER M
Use OUTER APPLY:
SELECT M.ID,
M.NAME
D.ID,
D.VALUE1
FROM dbo.[MASTER] M
OUTER APPLY(SELECT TOP 1 ID, VALUE1
FROM dbo.DETAIL
WHERE IDMASTER = M.ID
ORDER BY [DATE] DESC) D;
You do this with APPLY operator:
select * from master m
outer apply(select top 1 * from detail d where d.masterid = m.id order by d.date1 desc)oa
I need to add the results from a Left Join query to a table that does not have its index set to be an identity, but the int must still be unique. My insert query looks like this:
INSERT INTO Table1 (S.SubjectID, S.Subject, S.SubjectDescription, S.Status)
SELECT (Select MAX(SubjectID) FROM Table1) + ???? , N.Code, N.Literal, N.Trans
FROM Table2 N LEFT JOIN Table1 S ON N.Code = S.Subject
WHERE (N.Code IS NULL OR S.Subject IS NULL OR N.Trans = 'D')
Where I have the ???? is where i need to have some incrementing value so that when inserting into the table1 the ID's will be unique.
I am not allowed to change the table's structure, I just need something that can calculate his on the fly.
As always help, tips and references are much appreciated.
In most databases, you can use row_number() for this purpose. Here is an example with SQL Server syntax:
INSERT INTO Table1 (S.SubjectID, S.Subject, S.SubjectDescription, S.Status)
SELECT (Select MAX(SubjectID) FROM Table1) + row_number() over (order by (select NULL)) ,
N.Code, N.Literal, N.Trans
FROM Table2 N LEFT JOIN Table1 S ON N.Code = S.Subject
WHERE (N.Code IS NULL OR S.Subject IS NULL OR N.Trans = 'D')
I'm having trouble with a query I'm trying to write in oracle.
Basically I want to get the count of two tables that have the same provider list. I can run the query individually but not sure how to do it in one shot.
Here's a example:
SELECT name, COUNT(name)
FROM table1
group by name
This gives me a list of names and a count beside them. If I run the same command but on table2(changing the from statement), it works fine. What I want to do is have a query that takes count from table1 and substracts it from count from table2.
How can I do it? I have tried to do nested selects and so on but can't seem to get it to work.
One option assuming that the name values in both tables are identical would be
SELECT t1.name, t2.cnt - t1.cnt diff
FROM( SELECT name, COUNT(name) cnt
FROM table1
group by name ) t1,
( SELECT name, COUNT(name) cnt
FROM table2
group by name ) t2
WHERE t1.name = t2.name
If you want to handle the case where one table has a name that the other doesn't but you don't know which table has the extra name (and assuming that you want to say that the other table has a cnt of 0 for that name)
SELECT coalesce(t1.name, t2.name) name,
nvl(t1.cnt, 0 ) t1_cnt,
nvl(t2.cnt, 0 ) t2_cnt,
nvl(t2.cnt,0) - nvl(t1.cnt,0) diff
FROM( SELECT name, COUNT(name) AS cnt
FROM table1
group by table1.name ) t1
full outer join
( SELECT name, COUNT(name) AS cnt
FROM table2
group by table2.name ) t2
on( t1.name = t2.name )
which you can see in this SQLFiddle