Repeating values in single-column table - sql-server

I know this title isn't the best one, but i couldn't formulate a better one.
I have a function similar to STRING_SPLIT(), which return a single-column table with one row per split. What i need to do is keep the values from the other columns the same in the new rows.
I have a #TEMP Table with many lines like the following one:
INSERT INTO #TEMP([A], [ToSplit], [C], [D]) SELECT '549618', 'AAA, BBB', '1.7', '6'
I want to turn that line into two lines, one with AAA, the other with BBB, with the other values remaining equal.
I tried in the select list:
SELECT *, (SELECT * FROM [dbo].[ufn_split](ToSplit,',')) FROM #TEMP
ERROR: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Then as a condition (i used IN because it's the only that allow subqueries):
SELECT A, ToSplit FROM #TEMP
WHERE ToSplit IN (SELECT * FROM [dbo].[ufn_split](ToSplit,','))
No errors, but it only returns the rows that don't need the split. It would only work with LIKE, which is not allowed.
So i tried to put a subquery inside the method to create a single column table with one split value per row, that i would go row by row, use `LIKE %ToSplit% on the #TEMP, but again, subqueries not allowed.
SELECT * FROM [dbo].[ufn_split]((SELECT ToSplit FROM #TEMP),',')
ERROR: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
My question is, how can i split the values in ToSplit and keep the other columns values?

Please try like this .use CROSS APPLY
SELECT *
FROM #TEMP
CROSS APPLY
(
SELECT * FROM [dbo].[ufn_split](ToSplit,',')
)u

that will work on SQL SERVER 2016 and to unlimited values.
SELECT
t.*, LTRIM([value])
FROM #TEMP t
CROSS APPLY string_split([ToSplit], ',')

Related

How to dynamically replace a column value with another value based on condition

I am trying to dynamically change field value using a select query based on the person's previous room number.
Below are the data sample and the query I have tried. But it is throwing an error saying that there are multiple values returned by the inner query.
,A.[Room],A.[CSR],A.[MemberShip],A.[NatCode]
,A.[MarketCode],A.[Adult],A.[Children],A.[ArrDate]
,A.[DepDate],A.[ResvStatus], CASE WHEN A.[Room]>9000 THEN (SELECT MIN(A.[Room])FROM [RESDETAILS] C WHERE C.GuestName=A.GuestName) ELSE A.[Room] END AS [Room]
FROM [ITHAAFUSHI].[dbo].[RESDETAILS] A
WHERE [GuestName]= 'Mr Jobin Joseph'
GROUP BY
A.[BusinessDate],A.[GuestName],A.[TravelAgent]
,A.[Room],A.[CSR],A.[MemberShip],A.[NatCode]
,A.[MarketCode],A.[Adult],A.[Children],A.[ArrDate]
,A.[DepDate],A.[ResvStatus]
"Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, < =,>, >= or when the subquery is used as
an expression."
Below is the expected result when Room No is >9000
Your (SELECT MIN(A.[Room])FROM [RESDETAILS] C WHERE C.GuestName=A.GuestName)
return more than 1 row so you need to use group by inside :
SELECT MIN(A.[Room])FROM [RESDETAILS] C WHERE C.GuestName=A.GuestName GROUP BY C.GuestName)

When the following query is executed shows the following error

INSERT INTO tbl_vacancy_poojai
(vc_serial_no,vc_poojai_name,vc_poojai_amount,vc_poojai_time,
vc_book_date,vc_vacancy,vc_bok_poj,vc_type,vc_block)
VALUES (
(SELECT vc_serial_no FROM tbl_tot_vacancy_poojai),
(SELECT vc_poojai_name FROM tbl_tot_vacancy_poojai),
(SELECT vc_poojai_amount FROM tbl_tot_vacancy_poojai),
(SELECT vc_poojai_time FROM tbl_tot_vacancy_poojai),
'04/02/2018',
(SELECT vc_vacancy FROM tbl_tot_vacancy_poojai),
('04/02/2018'+(SELECT vc_serial_no FROM tbl_tot_vacancy_poojai)),
(SELECT vc_type FROM tbl_tot_vacancy_poojai),1)
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.**strong text
Can anyone guide me to solve this?
Good try. This is more like what you want:
INSERT INTO tbl_vacancy_poojai
(vc_serial_no,vc_poojai_name,vc_poojai_amount,vc_poojai_time,
vc_book_date,vc_vacancy,vc_bok_poj,vc_type,vc_block)
SELECT vc_serial_no,vc_poojai_name,vc_poojai_amount,
vc_poojai_time '04/02/2018',vc_vacancy,
'04/02/2018'+vc_serial_no,vc_type
FROM tbl_tot_vacancy_poojai
'04/02/2018'+vc_serial_no might not do what you think it does
The error occurred because of your select query returns more than one row. you need to select one record only to insert from the sub query. So specify the where condition or use select top 1.

inserting multiple rows into SQL

I'm trying to insert lots of rows into a 2 column table at once where one of the values remains constant. This is what I have tried: -
insert into testtable (value1,value2)
select
123,
( SELECT [title] FROM [dbo].[images])
This gives me the following error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
I could insert each row one at a time but I was wondering if there is a way I g=could do the whole lot in one go.
You have a syntax error, do not put two SELECT in there :
INSERT INTO testtable (value1,value2)
SELECT 123, [title]
FROM [dbo].[images];

Calculation between table with multiple rows

I am encountering a problem of doing calculation between table in multiple rows.
This is my code:
UPDATE StockList
SET stkQuantity = stkQuantity - (SELECT quantity FROM mCalculate)
WHERE stkID = (SELECT stkID FROM mCalculate)
If table mCalculate has only one row of data, the calculation in StockList is successfully, but if table mCalculate has multiple rows of data, I get an error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Can anyone help me solve this problem and explain to me what's the problem I am having?
Image to refer:
Window:
Database:
You have to use join instead of sub query in this case
UPDATE S
SET stkQuantity = stkQuantity - M.quantity
From stocklist s
Join mcalculate m
On s.stkid = m.stkid
Among other issues, this line here:
WHERE stkID = (SELECT stkID FROM mCalculate)
The = needs a single value, so unless your mCalculate table has only 1 row you will be getting errors.
Your error of: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. is most likely due to the WHERE clause.
Your sub-select
(SELECT quantity FROM mCalculate)
Needs a WHERE clause that ensures this select returns only one row. Ditto for this:
(SELECT stkID FROM mCalculate)
Without the SCHEMA definitions for these tables, it's hard to help you figure out exactly what that WHERE clause should be.

T-SQL First_Value() - How can it return more than a single value?

I have the following query:
Select PH.SubId
From dbo.PanelHistory PH
Where
PH.Scribe2Time <> (Select FIRST_VALUE(ReadTimeLocal) OVER (Order By ReadTimeLocal) From dbo.PanelWorkflow Where ProcessNumber = 2690 And dbo.PanelWorkflow.SubId = PH.SubId)
I'm getting an error (512) that says: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
How can the subquery return more than a single value? There can only be one first value. I must be overlooking something with this query.
By the way, I realize I could easily use Min() instead of First_Value, but I wanted to experiment with some of these Windowing functions.
How many rows do you see?
SELECT FIRST_VALUE(name) OVER (ORDER BY create_date) AS RN
FROM sys.objects
Even though there is only one distinct first value it still returns it for every row in the query.
So if the sub query itself matches multiple rows you will get this error. You could get rid of it with DISTINCT or TOP 1.
Probably not very efficient but you say this is just for experimental purposes.
This isn't an answer. It's just an extended comment generated by the following conclusion:
I could easily use Min() instead of First_Value, but I
wanted to experiment with some of these Windowing functions.
Min can't be used instead of FIRST_VALUE.
Example:
SET NOCOUNT ON;
DECLARE #MyTable TABLE(ID INT, TranDate DATETIME)
INSERT #MyTable VALUES (1, '2012-02-02'), (2, '2011-01-01'), (3, '2013-03-03')
SELECT MIN(ID) AS MIN_ID FROM #MyTable
SELECT ID, MIN(ID) OVER(ORDER BY TranDate) AS MIN_ID_ORDER_BY FROM #MyTable;
SELECT ID, FIRST_VALUE(ID) OVER(ORDER BY TranDate) AS FIRST_VALUE_ID_ORDER_BY FROM #MyTable;
Results:
MIN_ID
-----------
1
ID MIN_ID_ORDER_BY
----------- ---------------
2 2
1 1
3 1
ID FIRST_VALUE_ID_ORDER_BY
----------- -----------------------
2 2
1 2
3 2
FIRST_VALUE() will still return a row for every record that meets tour WHERE clause. TOP 1 should work:
Select PH.SubId
From dbo.PanelHistory PH
Where
PH.Scribe2Time <> (Select TOP 1 ReadTimeLocal
From dbo.PanelWorkflow
Where ProcessNumber = 2690
And dbo.PanelWorkflow.SubId = PH.SubId
Order By ReadTimeLocal DESC)
or MIN:
Select PH.SubId
From dbo.PanelHistory PH
Where
PH.Scribe2Time <> (Select MIN(ReadTimeLocal)
From dbo.PanelWorkflow
Where ProcessNumber = 2690
And dbo.PanelWorkflow.SubId = PH.SubId)
The PARTITION/OVER functions are look-ahead column functions. They aren't row functions - by that, I mean, they don't effect an entire row, number of rows returned, etc. An OVER aggregate can depend on values in other rows, but the tangible result is only to calculate a single column in the current row.
You may have seen something similar to what you are trying to do via an OVER ROW_NUMBER ranking function. Multiple rows are still returned, but only one of them has a ROW_NUMBER of 1. The rest are filtered in an encapsulating WHERE or JOIN predicate.

Resources