Insert Statement Error Message - sql-server

Good Morning All
My boss helped me design a query where it populates 1.37 million lines of random data, he has now asked me to insert/update the results into a blank table. But for some reason I cannot get it to work.
The three columns are ArrivalDate, PitchType_Skey and Site_Skey. But when I run my query (See below) I get an error message and I don't know why. Can you help?
Msg 121, Level 15, State 1, Line 2
The select list for the INSERT statement contains more items than the insert list. The number of SELECT values must match the number of INSERT columns.
Query:
USE Occupancy
INSERT INTO Bookings (ArrivalDate, Site_Skey, PitchType_Skey)
SELECT
Time.Date, Site.Site_Skey, Site.SiteWeighting, PitchType.PitchType_Skey,
PitchType.PitchTypeWeighting,
RAND(checksum(NEWID())) * Site.SiteWeighting * PitchType.PitchTypeWeighting AS Expr1
FROM
Capacity
INNER JOIN
Site ON Capacity.Site_Skey = Site.Site_Skey
INNER JOIN
PitchType ON Capacity.PitchType_Skey = PitchType.PitchType_Skey
INNER JOIN
Time
INNER JOIN
AGKey ON Time.ArrivalDayWeighting = AGKey.[Key] ON Capacity.StartDate <= Time.Date AND Capacity.EndDate >= Time.Date
CROSS JOIN
(SELECT 0 AS col1
UNION ALL
SELECT 1 AS col1) AS aaav
WHERE
(Time.CalendarYear = 2010)
AND (RAND(checksum(NEWID())) * Site.SiteWeighting * PitchType.PitchTypeWeighting >= 1.22)
Thanks
Wayne

The error message give you the answer. You have more items in your SELECT list (6)
Time.Date
Site.Site_Skey
Site.SiteWeighting
PitchType.PitchType_Skey
PitchType.PitchTypeWeighting
RAND(checksum(NEWID())) * Site.SiteWeighting * PitchType.PitchTypeWeighting AS Expr1
Than you do in your INSERT list (3)
ArrivalDate
Site_Skey
PitchType_Skey
Either remove some columns from your SELECT list or add some to your INSERT list.
As you haven't given the complete structure of your Bookings table I can only guess that you will need to do this
USE Occupancy
INSERT INTO Bookings
(
ArrivalDate,
Site_Skey,
PitchType_Skey
)
SELECT
Time.Date,
Site.Site_Skey,
PitchType.PitchType_Skey
FROM
Capacity
INNER JOIN Site ON Capacity.Site_Skey = Site.Site_Skey
INNER JOIN PitchType ON Capacity.PitchType_Skey = PitchType.PitchType_Skey
INNER JOIN Time
INNER JOIN AGKey ON Time.ArrivalDayWeighting = AGKey.[Key] ON Capacity.StartDate <= Time.Date AND Capacity.EndDate >= Time.Date
CROSS JOIN
(
SELECT 0 AS col1
UNION ALL
SELECT 1 AS col1
) AS aaav
WHERE
Time.CalendarYear = 2010
AND (RAND(checksum(NEWID())) * Site.SiteWeighting * PitchType.PitchTypeWeighting >= 1.22)

I have found the solution and I cant believe how easy it was, I just un-ticked the boxes I didn't want on the Query Designer.

Related

Need the sum of two columns from subquery

I have here my query and subquery to generate totals for the types I'm looking for in my database but now I need to somehow get the total for the entire columns. I feel like the solution is right in front of me but I cannot figure it out. Any step in the right direction would be greatly appreciated.
SELECT
SUM(b.aGiven) AS given,
SUM(b.aUsed) AS used
FROM UserAccountGroups AS uag
LEFT OUTER JOIN (
SELECT
uac1.UserAccountGroupID AS aGroupID,
SUM(ua.UserAccountUsedAmount) AS aUsed,
0 AS aGiven
FROM UserAccounts AS ua
LEFT OUTER JOIN UserAccountCodes AS uac1 ON ua.UserAccountCode = uac1.UserAccountCode
WHERE uac1.UserAccountCodeCreatedOn between '07-11-2020' and '07-11-2021'
GROUP BY uac1.UserAccountGroupID
UNION
SELECT
uac.UserAccountGroupID AS aGroupID,
0 AS aUsed,
SUM(uac.UserAccountCodeAmount) AS aGiven
FROM UserAccountCodes AS uac
LEFT OUTER JOIN UserAccounts AS ua1 ON uac.UserAccountCode = ua1.UserAccountCode
WHERE uac.UserAccountCodeCreatedOn between '07-11-2010' and '07-11-2021'
GROUP BY uac.UserAccountGroupID
) AS b ON b.aGroupID = uag.UserAccountGroupID
GROUP BY uag.ReportGroup
*** Update ***
I'm sorry if my question was unclear. This is a query I am using to pull the totals for each type of 'ReportGroup' from the db. Now, rather than needing the totals per group, I need the totals per the column. The idea is to pass in date variables in my codebehind to pull from custom dates and now I would like to have a grand total per column at the bottom of my report. I know I don't need to select any data from UserAccountGroups but I'm having trouble re-working the query to get accurate results. A point in the right direction would be very helpful and thank you beforehand.
If you can provide DML and DDL statements this could have tested easily. This will give sum for each aGroupID and grand total for columns aUsed, aGiven.
SELECT *
into #temp_agg_data
FROM
(
SELECT
uac1.UserAccountGroupID AS aGroupID,
SUM(ua.UserAccountUsedAmount) AS aUsed,
0 AS aGiven
FROM UserAccounts AS ua
LEFT OUTER JOIN UserAccountCodes AS uac1 ON ua.UserAccountCode = uac1.UserAccountCode
WHERE uac1.UserAccountCodeCreatedOn between '07-11-2020' and '07-11-2021'
GROUP BY uac1.UserAccountGroupID
UNION ALL
SELECT
uac.UserAccountGroupID AS aGroupID,
0 AS aUsed,
SUM(uac.UserAccountCodeAmount) AS aGiven
FROM UserAccountCodes AS uac
LEFT OUTER JOIN UserAccounts AS ua1 ON uac.UserAccountCode = ua1.UserAccountCode
WHERE uac.UserAccountCodeCreatedOn between '07-11-2010' and '07-11-2021'
GROUP BY uac.UserAccountGroupID
) AS A
--Last select will list down all records with sum group by [aGroupID] and grand total for [aUsed] , [aGiven] as a row below as 'Grand Total'
SELECT
[aGroupID]
,[aUsed]
,[aGiven]
FROM
#temp_agg_data
UNION ALL
SELECT
'Grand Total' AS [aGroupID]
, SUM(aUsed) as [aUsed]
, SUM(aUsed) as [aGiven]
FROM #temp_agg_data
DROP TABLE #temp_agg_data
You need to take out UserAccountGroupID in the select statements in order to get the Sum of all. Right now, you have UserAccountGroupID in the select, so it is summing by UserAccountGroupID. Hope this answers your question.
the reportGroup has not be used in the join with the subqueries so it can not be grouped by in the result query. Add the reportGroup to filter to the subqueries in the union. You don't need a union or union all sql.
declare #UserAccounts as table(UserAcccountGroupID int,UserAccountCode varchar(10),UserAccountUsedAmount money)
declare #UserAccountCodes as table (UserAccountCode varchar(10),UserAccountCodeCreatedOn Date,UserAccountGroupID int,UserAccountCodeAmount money)
declare #UserAccountGroups as table(UserAccountGroupID int,ReportGroup varchar(10));
select
IsNull(UserAccountCodes.aGiven,0) aGiven
,IsNull(UserAccounts.aUsed,0) aUsed
FROM #UserAccountGroups AS uag
OUTER APPLY
(
SELECT
--uac1.UserAccountGroupID AS aGroupID,
SUM(ua.UserAccountUsedAmount) AS aUsed
--0 AS aGiven
FROM #UserAccounts AS ua
LEFT JOIN #UserAccountCodes AS uac1
ON ua.UserAccountCode = uac1.UserAccountCode
WHERE uac1.UserAccountCodeCreatedOn between '07-11-2020' and '07-11-2021'
and uac1.UserAccountGroupID = uag.UserAccountGroupID
) UserAccounts
outer apply
(
SELECT
--uac.UserAccountGroupID AS aGroupID,
--0 AS aUsed,
SUM(uac.UserAccountCodeAmount) AS aGiven
FROM #UserAccountCodes AS uac
LEFT JOIN #UserAccounts AS ua1
ON uac.UserAccountCode = ua1.UserAccountCode
WHERE uac.UserAccountCodeCreatedOn between '07-11-2010' and '07-11-2021'
and uac.UserAccountGroupID = uag.UserAccountGroupID
) UserAccountCodes

How can I use outer join with subquery and groupby?

Tool : MySQL Workbench 6.3
Version : MySQL 5.7
SELECT *
FROM cars as a, battery_log as b
WHERE a.user_seq = 226 AND a.seq = b.car_seq
AND b.created = ( SELECT MAX(created) FROM battery_log WHERE car_seq = a.seq )
GROUP BY car_type
ORDER BY a.created DESC;
I want to turn this query into an outer join.
By searching user_seq in the'cars' table
I need to get the latest value of the battery log in the one-to-many relationship of the corresponding car table.
Sometimes the battery log does not have a value that matches car seq, so it is truncated from the joining process of table a and table b. How can I fix this?
SELECT a.*, b.battery
FROM cars as a
LEFT OUTER JOIN battery_log as b ON a.seq = b.car_seq
LEFT OUTER JOIN ( SELECT MAX(created) FROM battery_log WHERE a.seq = b.car_seq) as c
ON b.created = c.MAX(created)
WHERE a.user_seq = 226
GROUP BY car_type
ORDER BY a.created DESC
I tried to fix it this way, but I got the following error:
Error Code: 1054, Unknown column'a.seq' in'where clause'
I solved this problem like this.
SELECT *
FROM cars as a
LEFT OUTER JOIN battery_log as b ON a.seq = b.car_seq
AND b.created = (SELECT MAX(created) FROM battery_log WHERE car_seq = b.car_seq)
WHERE a.user_seq = 226
GROUP BY car_type
ORDER BY a.created DESC;
After LEFT OUTER JOIN ... ON, an additional condition was given with AND, and the query was performed according to the condition.

SQL Query Get Last record Group by multiple fields

Hi I have a table with following fields:
ALERTID POLY_CODE ALERT_DATETIME ALERT_TYPE
I need to query above table for records in the last 24 hour.
Then group by POLY_CODE and ALERT_TYPE and get the latest Alert_Level value ordered by ALERT_DATETIME
I can get up to this, but I need the AlertID of the resulting records.
Any suggestions what would be an efficient way of getting this ?
I have created an SQL in SQL Server. See below
SELECT POLY_CODE, ALERT_TYPE, X.ALERT_LEVEL AS LAST_ALERT_LEVEL
FROM
(SELECT * FROM TableA where ALERT_DATETIME >= GETDATE() -1) T1
OUTER APPLY (SELECT TOP 1 [ALERT_LEVEL]
FROM (SELECT * FROM TableA where ALERT_DATETIME >= GETDATE() -1) T2
WHERE T2.POLY_CODE = T1.POLY_CODE AND
T2.ALERT_TYPE = T1.ALERT_TYPE ORDER BY T2.[ALERT_DATETIME] DESC) X
GROUP BY POLY_CODE, ALERT_TYPE, X.[ALERT_LEVEL]
POLY_CODE ALERT_TYPE ALERT_LEVEL
04575 Elec 2
04737 Gas 3
06239 Elec 2
06552 Elec 2
06578 Elec 2
10320 Elec 2
select top 1 with ties *
from TableA
where ALERT_DATETIME >= GETDATE() -1
order by row_number() over (partition by POLY_CODE,ALERT_TYPE order by [ALERT_DATETIME] DESC)
The way this works is that for each group of POLY_CODE,ALERT_TYPE get their own row_number() starting from the most recent alert_datetime. Then, the with ties clause ensures that all rows(= all groups) with the row_number value of 1 get returned.
One way of doing it is creating a cte with the grouping that calculates the latesdatetime for each and then crosses it with the table to get the results. Just keep in mind that if there are more than one record with the same combination of poly_code, alert_type, alert_level and datetime they will all show.
WITH list AS (
SELECT ta.poly_code,ta.alert_type,MAX(ta.alert_datetime) AS LatestDatetime,
ta.alert_level
FROM dbo.TableA AS ta
WHERE ta.alert_datetime >= DATEADD(DAY,-1,GETDATE())
GROUP BY ta.poly_code, ta.alert_type,ta.alert_level
)
SELECT ta.*
FROM list AS l
INNER JOIN dbo.TableA AS ta ON ta.alert_level = l.alert_level AND ta.alert_type = l.alert_type AND ta.poly_code = l.poly_code AND ta.alert_datetime = l.LatestDatetime

TSQL - Get sum or substract from two tables

I want to sum/substract 'salevalue' from the two tables in my procedure. Sale 1 has receipts, 2nd is with returns. But I am lost in ideas.
SELECT *
FROM #possale1
SELECT *
FROM #possale2
SELECT sum(salevalue) AS S1
FROM #possale1
SELECT sum(salevalue)*-1 AS S2
FROM #possale2
select sum(sum(a.salevalue)-sum(b.salevalue))
from #possale1 a
inner join #possale2 b on a.receiptdate=b.receiptdate
Without aggregation next should do:
select ((SELECT sum(salevalue) FROM #possale1) - (SELECT sum(salevalue) FROM #possale2)) as balance
Are you trying for this ?
SELECT SUM(ISNULL(a.salevalue,0) - ISNULL(b.salevalue,0))
FROM #possale1 a FULL OUTER JOIN #possale2 b on a.receiptdate=b.receiptdate

Using the results of WITH clause IN where STATEMENT of main query

I am relatively new at SQL so I apologise if this is obvious but I cannot work out how to use the results of the WITH clause query in the where statement of my main query.
My with query pulls the first record for each customer and gives the sale date for that record:
WITH summary AS(
SELECT ed2.customer,ed2.saledate,
ROW_NUMBER()OVER(PARTITION BY ed2.customer
ORDER BY ed2.saledate)AS rk
FROM Filteredxportdocument ed2)
SELECT s.*
FROM summary s
WHERE s.rk=1
I need to use the date in the above query as the starting point and pull all records for each customer for their first 12 months i.e. where the sale date is between ed2.saledate AND ed2.saledate+12 months.
My main query is:
SELECT ed.totalamountincvat, ed.saledate, ed.name AS SaleRef,
ed.customer, ed.customername, comp.numberofemployees,
comp.companyuid
FROM exportdocument AS ed INNER JOIN
FilteredAccount AS comp ON ed.customer = comp.accountid
WHERE (ed.statecode = 0) AND
ed.saledate BETWEEN ed2.saledate AND DATEADD(M,12,ed2.saledate)
I am sure that I need to add the main query into the WITH clause but I cant work out where. Is anyone able to help please
Does this help?
;WITH summary AS(
SELECT ed2.customer,ed2.saledate,
ROW_NUMBER()OVER(PARTITION BY ed2.customer
ORDER BY ed2.saledate)AS rk
FROM Filteredxportdocument ed2)
SELECT ed.totalamountincvat, ed.saledate, ed.name AS SaleRef,
ed.customer, ed.customername, comp.numberofemployees,
comp.companyuid
FROM exportdocument AS ed INNER JOIN
FilteredAccount AS comp ON ed.customer = comp.accountid
OUTER APPLY (SELECT s.* FROM summary s WHERE s.rk=1) ed2
WHERE ed.statecode = 0 AND
ed.saledate BETWEEN ed2.saledate AND DATEADD(M,12,ed2.saledate)
and ed.Customer = ed2.Customer
Results of CTE are not cached or stored, so you can't reuse it.
EDIT:
Based upon your requirement that all the records from CTE should be in final result, this is a new query:
;WITH summary AS(
SELECT ed2.customer,ed2.saledate,
ROW_NUMBER()OVER(PARTITION BY ed2.customer
ORDER BY ed2.saledate)AS rk
FROM Filteredxportdocument ed2)
SELECT
ed.totalamountincvat,
ed.saledate,
ed.name AS SaleRef,
ed.customer,
ed.customername,
comp.numberofemployees,
comp.companyuid
FROM
summary ed2
left join exportdocument ed
on ed.Customer = ed2.Customer
and ed.statecode = 0
AND ed.saledate BETWEEN ed2.saledate AND DATEADD(M,12,ed2.saledate)
INNER JOIN FilteredAccount comp
ON ed.customer = comp.accountid
WHERE
s.rk=1
summary you will be able to use only once. Alternate solution is store summary into temp table and use that as many times as u want.
Something like : Select * into #temp from Summary s where s.rk=1

Resources