I've looked all over for help on this but nothing seems to be working.
I have the following statement in an SP that fails with the collate error each time:
INSERT INTO #TableR (id, email, forename, Age, gender)
SELECT TOP 1 #TEMPMDUK.id AS [id], email, forename, Age, gender
FROM #TEMPMDUK
WHERE SUBSTRING(postcode, 0, (CHARINDEX(' ', postcode, 0)+2)) in (select Postcode from LiveTable)
and not #TEMPMDUK.ID in (SELECT id FROM #Excludelist)
and #TEMPMDUK.ID in (SELECT id FROM #Includelist)
ORDER BY NEWID()
It only started to happen after we added the following clause to the statement:
WHERE SUBSTRING(postcode, 0, (CHARINDEX(' ', postcode, 0)+2)) in (select Postcode from LiveTable)
If we run this as a clause in a select statement everything is fine but when we put it into the INSERT statement in the SP it breaks.
Any help to resolve this would be much appreciated, thanks.
I don`t know your table structures but it seems that you have different collations in columns. Try playing with
SELECT TOP 1 #TEMPMDUK.id AS [id], email COLLATE Latin1_General_CI_AS, forename, Age, gender
Or
SELECT TOP 1 #TEMPMDUK.id AS [id], email COLLATE SQL_Latin1_General_CP1_CI_AS, forename, Age, gender
Related
I have a select query which returns a couple of rows grouped by ParentId. How can I add a new row with sum of a column after each parentId group?
For now I have kept the data in a temp table and the result is as below.
And I want to add a new row at the end of each ParentId group as below with the sum of column LoanAmount.
Any help will be appreciated. Many thanks.
You can use a common table expression to achieve this. Here I've created a cte with rank column for getting it sorted in order.
;WITH cte AS
(SELECT ParentId,
sum(LoanAmount) LoanAmount,
max(rank) + 1 AS rank
FROM test
GROUP BY ParentId)
SELECT *
FROM test
UNION ALL
SELECT *
FROM cte
ORDER BY ParentId, rank
rextester
See this link here enter link description here
I think you want:
SELECT ParentID, SUM(VALUE1), SUM(VALUE2)
FROM tableName
GROUP BY ID
You cant do it after each group or at the bottom like in excel, but you create a 'new table' in your query effectively.
Yeah having seen your updated comment, you main issue is youre thinking of it like excel, SQL is not a spreadsheet tool - its a relational database. Id suggest going through a SQL intro - youll pick up the concepts quite fast.
The query I gave you could be created as a stored procedure.
If you feel I've answered your question, id appreciate an upvote :)
You can make sum of group by subquery then combine them in union
; with cte as
( select 9999 as Slno, Level, ParentId, Ent_id, relation, sum(colname) as colname from table group by Level, ParentId, Ent_id, relation)
, ct as ( select row_number() over (partition by ParentId order by level) as Slno, Level, ParentId, Ent_id, Name, --- rest of your column names
colname from table
union all
select Slno, Level, ParentId, Ent_id, '' as Name, ---rest of '' for each column with column name as alias
colname from cte )
select Slno, Level, ParentId, Ent_Id, Name, ---- your columns of table
colname from ct order by Slno
This is just rough idea. Feel free to ask for any confusion.
Post your exact schema for accurate details.
I have Employees tables in the database with a column EmpID which was changed to ID. I want to use the same query in both the old and new table and get the same result depending on the condition.
I have tried the following:
IF (COL_LENGTH('Employees', 'EmpID') IS NOT NULL)
SELECT EmpID, NAME, SEX, SALARY
FROM Employees
WHERE EmpID IS NOT NULL
ELSE
SELECT ID, NAME, SEX, SALARY
FROM Employees
WHERE ID IS NOT NULL
But when I run the query in the new table, I get column name EmpID doesn't exist error. Any help is appreciated!
You can do this without dynamic SQL using this approach.
SELECT ISNULL(CA.ID, CA.EmpID) AS ID,
CA.NAME,
CA.SEX,
CA.SALARY
FROM (VALUES(NULL, NULL)) V(ID, EmpID)
CROSS APPLY (SELECT ID, /*Resolved from Employees if present or "V" otherwise */
EmpID, /*Resolved from Employees if present or "V" otherwise */
NAME,
SEX,
SALARY
FROM Employees) CA
WHERE ISNULL(CA.ID, CA.EmpID) IS NOT NULL;
Demo
The issue is the compile stage versus the execution stage. The code is initially compiled, where the tables and columns are validated.
Your problem is that the column doesn't exist, so you are getting a compile failure.
You can fix this using dynamic SQL:
DECLARE #sql NVARCHAR(max);
IF (COL_LENGTH('Employees', 'EmpID') IS NOT NULL)
SET #sql = N'
Select EmpID, NAME, SEX, SALARY
From Employees
Where EmpID IS NOT NULL'
ELSE
SET #sql = N'
Select ID, NAME, SEX, SALARY
From Employees
Where ID IS NOT NULL'
EXEC sp_executesql #sql;
I am trying to (select)query inside the previous (select)query from same table.
I've tried this below;
CREATE PROCEDURE dbo.strprcReturnEmpDetails(#EmpID VARCHAR(25))
AS
SELECT [Name],
Role,
Email,
Department,
ReportingAuthority,
DomainID,
ReportsTo,
(
SELECT DISTINCT
EmpID
FROM Login
WHERE [Name] = ReportsTo
) AS approverEmpid
FROM Login
WHERE EmpID = 288;
SET NOCOUNT ON;
RETURN;
I believe you just miss the aliases in the subquery to make it work. Your subquery returns more than one value, you need to make it a dependent subquery as follows:
SELECT [Name], Role, Email, Department, ReportingAuthority,DomainID,ReportsTo,
(
select distinct EmpID
from Login l2
where l2.Name = l1.ReportsTo
) as approverEmpid
FROM Login l1
WHERE EmpID=288
This should work if Name in Login table is unique.
I need a query in MSSQL to return the following result:
Client ID, UserName, EventDate
distinctly for each ClientID based on the most recent date from the following table :
e.g : Given the table above, return :
450SB 2013-03-01 16:40:29 nevadan
LASB 2013-03 001 16:37:27 siteuser
etc
Was thinking of creating a cursor for a : SELECT DISTINCT ClientId from TABLE
and looping through each returning only entry of maxdate, but didn't think it
was very efficient.
You can use a CTE to grab the latest access dates for each client, then JOIN back on the CTE to get the username for each of the latest access dates for each client. The JOIN would be better in terms of performance, readability, and elegance if your table had a primary key though.
;WITH latestClientAccess (ClientId, LatestEventDate) AS (
SELECT ClientId, MAX(EventDate)
FROM MyTable
GROUP BY ClientId
)
SELECT t.ClientId, t.UserName, lca.LatestEventDate [EventDate]
FROM MyTable t
INNER JOIN latestClientAccess lca
ON t.ClientId=lca.ClientId
AND t.EventDate=lca.LatestEventDate
A quick local test for the concept and script above can be performed by running the script below. This way, anyone else looking at this response can test without having to create any schema.
declare #temp table(ClientId int, EventDate datetime, UserName varchar(20))
insert into #temp
select 1, '2015-11-06 00:00:00', 'user1'
insert into #temp
select 2, '2015-11-06 00:01:00', 'user1'
insert into #temp
select 1, '2015-11-06 00:01:00', 'user2'
insert into #temp
select 1, '2015-11-06 00:03:00', 'user1'
;WITH latestClientAccess (ClientId, LatestEventDate) AS (
SELECT ClientId, MAX(EventDate)
FROM #temp
GROUP BY ClientId
)
SELECT t.ClientId, t.UserName, lca.LatestEventDate [EventDate]
FROM #temp t
INNER JOIN latestClientAccess lca
ON t.ClientId=lca.ClientId
AND t.EventDate=lca.LatestEventDate
EDIT
Considering you do have a primary key and a second table with the client name, consider the scripts below:
;WITH latestClientAccess (ClientId, HistoryId) AS (
SELECT ClientId, MAX(HistoryId)
FROM MyTable
GROUP BY ClientId
)
SELECT ct.ClientName, t.UserName, t.EventDate
FROM MyTable t
INNER JOIN latestClientAccess lca
ON t.HistoryId=lca.HistoryId
INNER JOIN MyClientTable ct
ON t.ClientId=ct.ClientId
For quick test of latest event concept (without client name):
declare #temp table(HistoryId int, ClientId int, EventDate datetime, UserName varchar(20))
insert into #temp
select 1, 1, '2015-11-06 00:00:00', 'user1'
insert into #temp
select 2, 2, '2015-11-06 00:01:00', 'user1'
insert into #temp
select 3, 1, '2015-11-06 00:01:00', 'user2'
insert into #temp
select 4, 1, '2015-11-06 00:03:00', 'user1'
;WITH latestClientAccess (ClientId, HistoryId) AS (
SELECT ClientId, MAX(HistoryId)
FROM #temp
GROUP BY ClientId
)
SELECT t.ClientId, t.UserName, t.EventDate
FROM #temp t
INNER JOIN latestClientAccess lca
ON t.HistoryId=lca.HistoryId
I don't have MSSQL installed on my computer so I can't test this for you but alternatively I think you can add the "ORDERBY ASC eventdate" filter to your SQL and then only select the first row to achieve your goal.
So it will be something like
SELECT DISTINCT ClientId
FROM TABLE
ORDER BY eventdate
As to whether this is more efficient or not... I think you willl have to look at the query execution plan to see what operations are done by the MSSQL to do the query, performance wise probably not as good as your previous one because this SQL is doing something extra, that is sorting.
With this approach at least you don't have to think of efficient sort algorithm yourself and it saves you time thinking of the algorithm and couple lines of code :P
What you are describing is a little more complicated than one would think, mostly because you need UserName in addition to ClientID and EventDate.
This should work, although I didn't build your schema up locally to test, so let me know if you get any errors.
SELECT
t1.*
FROM
SomeTable t1
INNER JOIN
(
SELECT
ClientId
MaxEventDate = MAX(EventDate)
FROM
SomeTable
GROUP BY
ClientId
) t2
ON
t1.ClientID = t2.ClientID
AND t1.EventDate = t2.EventDate
...note: if you get rid of UserName it's just:
SELECT
ClientId
MaxEventDate = MAX(EventDate)
FROM
SomeTable
GROUP BY
ClientId
I am trying to insert into a table from a select statement as well as add additional parameters to the rows with something like-
SELECT
Appt_ID,
Pracitioner_ID,
Appt_Book_ID,
Start_Time,
UR_NO,
[Type],
[Description]
FROM #TempWaiting,
#EndTime,
#PatientID,
#Title,
#FirstName,
#LastName,
#Surname,
#DOB
INTO PS_WAITING_LIST(Appt_ID,
Pracitioner_ID,
Appt_Book_ID,
Start_Time,
UR_NO,
[Type],
[Description],
End_Time,
Patient_ID,
Title,
First_Name,
Middle_Name,
Surname,
DOB)
This is within a stored procedure and all it says is error after INTO.
I also tried re-writing it as -
insert into PS_WAITING_LIST (
Appt_ID,
Pracitioner_ID,
Appt_Book_ID,
Start_Time,
UR_NO,
[Type],
[Description],
End_Time,
Patient_ID,
Title,
First_Name,
Middle_Name,
Surname,
DOB)
SELECT
Appt_ID,
Pracitioner_ID,
Appt_Book_ID,
Start_Time,
UR_NO,
[Type],
[Description]
FROM #TempWaiting,
#EndTime,
#PatientID,
#Title,
#FirstName,
#LastName,
#Surname,
#DOB
This throws an error saying the number of select value must match the number of insert column. Well obviously that does not.
I also tried Insert into table (col1, col2..) Select * from (select (...), col3, col9)
Generally it works like this
insert into your_table (col1, col2, col3)
select some_column, #aVariable, 'static_string'
from another_table
If you have a table with many columns listing them all out can be tedious. To add a column to the end of the insert, for instance, a loggedAT or recreatedAt timestamp the following can be done. First create a dts column as the last column, then
INSERT INTO users_log SELECT *, NOW() FROM users WHERE id=?;
In this instance, we now know when the column has been added to our users_log table. The final case would be we may also want a primary key that is specific to the users_log table. lets modify the users_log table once more by adding a 'key' column to the end of the table setting it to be PK, AUTO, UNSIGNED. We can now populate that id with:
INSERT INTO users_log SELECT *, NOW(), '' FROM users WHERE id=?;
Now we have an exact copy of the user record including the PK from the user table and in our users_log table we can now track when the record was copied over and produce its own PK. Note that the users_log table would need to be modified to remove the PK from id that would have been from the users table to prevent id conflicts.
assuming that #tempWaiting is a variable table the statement should be like this.
insert into PS_WAITING_LIST (
Appt_ID,
Pracitioner_ID,
Appt_Book_ID,
Start_Time,
UR_NO,
[Type],
[Description],
End_Time,
Patient_ID,
Title,
First_Name,
Middle_Name,
Surname,
DOB)
SELECT
Appt_ID,
Pracitioner_ID,
Appt_Book_ID,
Start_Time,
UR_NO,
[Type],
[Description],
#EndTime,
#PatientID,
#Title,
#FirstName,
#LastName,
#Surname,
#DOB
FROM #TempWaiting
You may also try the following:
Insert Into CustomerNew (CustomerId, CustomerName)
SELECT CustID, Name
FROM CustomerOld WHERE CustomerId Is not Null
I have two tables, table first and second
The first table contains products and prices
The second table has column month and column total
I wanted to update the second table with the sum of products in the first table plus month.
I found this query useful I think you might play around to solve your problem
INSERT INTO second (month, total) SELECT 'JANUARY' SUM(PRICE) AS TOTAL FROM first
In my specific case the id field in both tables was auto-incrementing so when I merged the tables, one inside the other, it threw an error because some id's matched.
to correct this you have to call the 'nextval' function (I'm using postgres). The complete syntax would be:
insert into your_table select nextval('your_table_id_seq') AS id, column_1, column_2, column_3, 'static_string' AS column_name from another_table.