I've created a Table-valued function in SQL server called dba.pp_Datasource_IL1201_Auto_Vehicles. The resulting dynamic data is going to flow to a PDF form. When I just query the second select that has the UNPIVOT operator, the data flows perfectly fine to the PDF and displays as desired in SSMS. However, when I add other columns, I get this error
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
DESIRED RESULT:
Column A
Column B
DATA 1
UNPIV DATA
NULL
UNPIV DATA
NULL
UNPIV DATA
NULL
UNPIV DATA
NULL
UNPIV DATA
NULL
UNPIV DATA
NULL
UNPIV DATA
NULL
UNPIV DATA
NULL
UNPIV DATA
NULL
UNPIV DATA
SELECT book_veh_num,
(select description
FROM
(
SELECT
convert(varchar(255), veh_status) as veh_status,
convert(varchar(255), veh_num) as veh_num,
convert(varchar(255), veh_year) as veh_year,
convert(varchar(255), veh_make) as veh_make,
convert(varchar(255), veh_model) as veh_model,
convert(varchar(255), veh_vin) as veh_vin,
convert(varchar(255), veh_cost_new) as veh_cost_new,
convert(varchar(255), veh_garage_loc) as veh_garage_loc,
convert(varchar(255), veh_class_code) as veh_class_code,
convert(varchar(255), ' ') as blank_line
FROM dba.pp_Datasource_IL1201_Auto_Vehicles(8589100, 'BusAuto')
) d
UNPIVOT
( description for vehicle in
(veh_status, veh_num, veh_year, veh_make, veh_model, veh_vin, veh_cost_new, veh_garage_loc, veh_class_code, blank_line)
) unpiv)
FROM dba.pp_Datasource_IL1201_Auto_Vehicles(8589100, 'BusAuto')
I suspect the problem is that you've used a subquery, rather than derived table. This is impossible to test, as we have no sample data, but perhaps this is what you want:
SELECT description, vehicle
FROM (SELECT CONVERT(varchar(255), veh_status) AS veh_status,
CONVERT(varchar(255), veh_num) AS veh_num,
CONVERT(varchar(255), veh_year) AS veh_year,
CONVERT(varchar(255), veh_make) AS veh_make,
CONVERT(varchar(255), veh_model) AS veh_model,
CONVERT(varchar(255), veh_vin) AS veh_vin,
CONVERT(varchar(255), veh_cost_new) AS veh_cost_new,
CONVERT(varchar(255), veh_garage_loc) AS veh_garage_loc,
CONVERT(varchar(255), veh_class_code) AS veh_class_code,
CONVERT(varchar(255), ' ') AS blank_line
FROM dba.pp_Datasource_IL1201_Auto_Vehicles(8589100, 'BusAuto') ) d
UNPIVOT (description
FOR vehicle IN (veh_status, veh_num, veh_year, veh_make, veh_model, veh_vin, veh_cost_new, veh_garage_loc, veh_class_code, blank_line)) unpiv;
Alternatively, you could unpivot your data with a VALUES table construct:
SELECT V.ColumnValue,
V.ColumnName
FROM dba.pp_Datasource_IL1201_Auto_Vehicles(8589100,N'BusAuto')DIAV
CROSS APPLY (VALUES(CONVERT(varchar(255), veh_status),N'veh_status'),
(CONVERT(varchar(255), veh_num),N'veh_num'),
(CONVERT(varchar(255), veh_year),N'veh_year'),
(CONVERT(varchar(255), veh_make),N'veh_make'),
(CONVERT(varchar(255), veh_model),N'veh_model'),
(CONVERT(varchar(255), veh_vin),N'veh_vin'),
(CONVERT(varchar(255), veh_cost_new),N'veh_cost_new'),
(CONVERT(varchar(255), veh_garage_loc),N'veh_garage_loc'),
(CONVERT(varchar(255), veh_class_code),N'veh_class_code'),
(CONVERT(varchar(255), ' '),N'blank_line'))V(ColumnValue,ColumnName);
Here's a sample pivot query with some data. I'm guessing you're doing correlated subquery to get casts correct, but you can instead prepare everything in a subquery:
drop table #car
create table #car (vin int, make varchar(30), color varchar(30), cost int)
insert into #car (vin, make, color, cost)
select 1234, 'BMW', 'Red', 99999
union
select 1235, 'Mercedes', 'Blue', 100000
union
select 1236, 'Volvo', 'Silver arrow', 3000
select vin, vehicle, description
from (
select vin, make, color, cast(cost as varchar(30)) AS cost
from #car
) x
unpivot (description for vehicle in (make, color, cost)) v
Related
I have a reference table that's currently delimited with '-' that I'm needing to split the values out into multiple columns. Our version of SQL DB doesn't support the string_split function.
The first part of the script (multiple CTE) is returning the results into multiple rows, which I'm then wanting to pivot into columns.
Is someone able to please assist with the PIVOT portion (or even a new statement if it achieves the same result). Am looking to have the results returned per final table format?
Thanks
Original Data:
ID
Value
Description
1
MV-RUC-DEBT-ASSESS
MV Debt Assessment
declare #T table (ID int, Col varchar(100), description varchar(50))
insert into #T values (1, 'MV-RUC-DEBT-ASSESS', 'MV Debt Assessment')
;
with cte as (
select a.ID
,replace(a.Col,'-', ' ') as "Col"
, a.description
from #T a
),
cte2 as (
select a.ID
, n.r.value('.', 'varchar(50)') "Value"
, a.description
from cte a
cross apply (select cast('<r>'+replace(replace(Col,'&','&'), ' ', '</r><r>')+'</r>' as xml)) as S(XMLCol)
cross apply S.XMLCol.nodes('r') as n(r)
)
select *
from cte2 a
pivot
(max(value) for a.ID in ([1], [2], [3], [4])) as "Pivot"
I'm expecting the results to look like
ID
Description
1
2
3
4
1
MV Debt Assessment
MV
RUC
DEBT
ASSESS
When you use a.ID as part of the pivot, it has only ones so that you only would get the max value of value.
adding a row_number would give you the wanted result
declare #T table (ID int, Col varchar(100), description varchar(50))
insert into #T values (1, 'MV-RUC-DEBT-ASSESS', 'MV Debt Assessment')
;
with cte as (
select a.ID
,replace(a.Col,'-', ' ') as "Col"
, a.description
from #T a
),
cte2 as (
select a.ID
, n.r.value('.', 'varchar(50)') "Value"
, row_number() OVER(PARTITION BY a.ID ORDER BY a.ID) rn
, a.description
from cte a
cross apply (select cast('<r>'+replace(replace(Col,'&','&'), ' ', '</r><r>')+'</r>' as xml)) as S(XMLCol)
cross apply S.XMLCol.nodes('r') as n(r)
)
select *
from cte2 a
pivot
(max(value) for a.rn in ([1], [2], [3], [4])) as "Pivot"
ID
description
1
2
3
4
1
MV Debt Assessment
MV
RUC
DEBT
ASSESS
fiddle
I have to put some columns and group them together by STRING_AGG also I want to put number first of each rows
What I have:
Name
Cake
Coca
ice-cream
Same
one
five
six
Sara
one
one
NULL
John
two
two
NULL
I want the output be something like this:
Name
Description
Sam
1.two 2.five 3. six
Sara
1.one 2.one
John
1.two 2.two
My Code:
SELECT Name, STRIN_AGG(CONCAT(Cake, ' ,', Coca,' ,', ice-cream))
FROM FoodTable
but I do not know how to consider numbers first of each rows in STRING_AGG
You don't need string_agg():
select name,
concat('1.' + cake, ' 2.' + coca, ' 3.' + ice_cream)
from t;
Note that + returns NULL if any value is NULL. However, concat() simply ignores NULL values.
If you really, really wanted to use string_agg() you could:
select t.name, v.all_together
from t cross apply
(select string_agg(v.n + v.val, ' ') within group (order by v.n) as all_together
from (values ('1.', t.cake),
('2.', t.coca),
('3.', t.ice_cream)
) v(n, val)
) v;
Here is a complete dynamic sql approach. No need to serialize and deserialize the data using XML or JSON. In this case the list of food items is contained in a temporary table so it reads the column names from tempdb.sys.columns.
The query uses CROSS APPLY to unpivot the columns (of food items) and assigns a ROW_NUMBER() to each non NULL item value. Something like this
drop table if exists #FoodTable;
go
create table #FoodTable(
[Name] varchar(100) not null,
Cake varchar(100) null,
Coca varchar(100) null,
[ice-cream] varchar(100) null);
--select * from dbo.test_actuals
insert #FoodTable values
('Sam', 'one', 'five', 'six'),
('Sara', 'one', 'one', null),
('Jon', 'two', 'two', null);
;with unpvt_cte([Name], item, val, rn) as (
select f.[Name], v.*, row_number() over (partition by [Name] order by (select null))
from #FoodTable f
cross apply (values ('Cake', Cake),
('Coca', Coca),
('IceCream', [ice-cream])) v(item, val)
where v.val is not null)
select [Name], string_agg(concat(rn, '.', val), ' ') within group (order by rn) answer
from unpvt_cte
group by [Name];
Name answer
Jon 1.two 2.two
Sam 1.one 2.five 3.six
Sara 1.one 2.one
to make the query dynamic
declare #food_list nvarchar(max);
select #food_list=string_agg(quotename(concat_ws(',', quotename(sysc.[name], ''''),
quotename(sysc.[name], '[]')), '()'), ',')
from tempdb.sys.columns sysc
where object_id = Object_id('tempdb..#FoodTable')
and [name]<>'Name';
declare
#sql_prefix nvarchar(max)=N'
;with unpvt_cte([Name], item, val, rn) as (
select f.[Name], v.*, row_number() over (partition by [Name] order by (select null))
from #FoodTable f
cross apply (values ',
#sql_suffix nvarchar(max)=N'
) v(item, val)
where v.val is not null)
select [Name], string_agg(concat(rn, ''.'', val), '' '') within group (order by rn) answer
from unpvt_cte
group by [Name];';
declare
#sql nvarchar(max)=concat(#sql_prefix, #food_list, #sql_suffix);
print(#sql);
exec sp_executesql #sql;
The print statement outputs the following
;with unpvt_cte([Name], item, val, rn) as (
select f.[Name], v.*, row_number() over (partition by [Name] order by (select null))
from #FoodTable f
cross apply (values ('Cake',[Cake]),('Coca',[Coca]),('ice-cream',[ice-cream])
) v(item, val)
where v.val is not null)
select [Name], string_agg(concat(rn, '.', val), ' ') within group (order by rn) answer
from unpvt_cte
group by [Name];
You may use a union to acquire the numbers for each column. Here I've used a cte but you could have used a subquery. Each query in the union renames the food type column to food and adds a column num that will be used in the final query. In the final query the where clause filters NULL foods and a group by with the string_agg and concat is used to retrieve the data in the desired format. I've included a working fiddle below:
WITH FoodTableNums AS (
SELECT Name, Cake as food, 1 as num FROM FoodTable UNION ALL
SELECT Name, Coca as food, 2 as num FROM FoodTable UNION ALL
SELECT Name, icecream as food, 3 as num FROM FoodTable
)
SELECT
Name,
STRING_AGG(CONCAT(num,'.', food),',' ) WITHIN GROUP( ORDER BY num asc) as Description
FROM
FoodTableNums
WHERE
food IS NOT NULL
GROUP BY
Name
Name
Description
John
1.two,2.two
Sam
1.one,2.five,3.six
Sara
1.one,2.one
db<>fiddle here
Let me know if this works for you.
Here is an option that is a bit more dynamic. You only have to Exclude certain columns ... in this case NAME
We use a bit of JSON to dynamically UNPIVOT the row, and then string_agg() to consolidate.
Example or dbFiddle
Select A.Name
,B.NewValue
From YourTable A
Cross Apply (
Select NewValue=STRING_AGG(concat(Seq,'.',Value),' ') within group (order by Seq)
From (
Select [Key]
,[Value]
,[Seq] = row_number() over (order by ##spid)
From OpenJson( (Select A.* For JSON Path,Without_Array_Wrapper ) )
Where [Key] not in ('Name')
) B1
) B
Results
Name NewValue
Same 1.one 2.five 3.six
Sara 1.one 2.one
John 1.two 2.two
Here is s generic way regardless of how many columns in a table.
It is based on XML/XQuery.
No need to UNPIVOT the rows, and then STRING_AGG() to consolidate.
All data in each row stays in a row.
SQL
-- DDL and data population, start
DECLARE #tbl table (
[Name] varchar(100) not NULL PRIMARY KEY,
Cake varchar(100) null,
Coca varchar(100) null,
[ice-cream] varchar(100) null);
INSERT #tbl VALUES
('Sam', 'one', 'five', 'six'),
('Sara', 'one', 'one', null),
('Jon', 'two', 'two', null);
-- DDL and data population, end
SELECT p.[Name]
, x.query('
for $r in /root/*[local-name()!="Name"]/text()
let $pos := count(root/*[. << $r]) - 1
return concat(string($pos), ".", $r)').value('text()[1]', 'VARCHAR(MAX)') AS Result
FROM #tbl AS p
CROSS APPLY (SELECT * FROM #tbl AS c
WHERE c.[Name] = p.[Name]
FOR XML PATH(''), TYPE, ROOT('root')) AS t(x);
Output
+------+--------------------+
| Name | Result |
+------+--------------------+
| Jon | 1.two 2.two |
| Sam | 1.one 2.five 3.six |
| Sara | 1.one 2.one |
+------+--------------------+
Although I agree with those saying that it would be much better to normalise your tables, but if you can't do that then this proposal makes GGordon's solution dynamic, building an SQL statement that retrieves all the columns on your FoodTable. No matter if they are 3 or 100 food columns.
CREATE TABLE FoodTable (
Name VARCHAR(4),
Cake VARCHAR(3),
Coca VARCHAR(4),
icecream VARCHAR(4)
);
INSERT INTO FoodTable ("Name", "Cake", "Coca", "icecream")
VALUES ('Sam', 'one', 'five', 'six'),
('Sara', 'one', 'one', NULL),
('John', 'two', 'two', NULL);
declare #SQL nvarchar(max);
WITH Food As (
SELECT ORDINAL_POSITION - 1 AS Num, COLUMN_NAME AS Food
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'FoodTable' AND COLUMN_NAME <> 'Name'
)
SELECT #SQL = N'WITH FoodTableNums AS ( ' +
string_agg('SELECT Name, ' + Food + ' as Food, ' + convert(varchar(20), Num) + ' as Num FROM FoodTable', ' UNION ALL ') +
') SELECT Name, STRING_AGG(CONCAT(num,''.'', food),'','' ) WITHIN GROUP( ORDER BY num asc) as Description FROM FoodTableNums WHERE food IS NOT NULL GROUP BY Name'
FROM Food;
EXECUTE sp_ExecuteSQL #SQL;
You can see it working here : Fiddle
I want execute this procedure, but SQL tell me this error 'The type of column "q82" conflicts with the type of other columns specified in the UNPIVOT list"
al the Q's are INT
Does somebody know solution?
INSERT INTO
[stg].[fact_answer_cc]
(
[user_id],
[question_id],
[answer],
[check_sum]
)
SELECT
[q2] AS [user_id],
[question_id],
[answer],
HASHBYTES (
N'SHA1',
ISNULL ( CAST([q2] AS VARCHAR), '' ) + #pipe_delimiter +
ISNULL ( CAST([question_id] AS VARCHAR), '' )
) AS [check_sum]
FROM
(
SELECT
[q2],
[q80],
[q81],
[q82],
[q83],
[q84],
[q85],
[q86],
[q87],
[q88],
[q89],
[q90],
[q91],
[q92]
FROM
[src].[qa_data_cc]
) AS t
UNPIVOT
(
[answer] FOR [question_id] IN
(
[q80],
[q81],
[q82],
[q83],
[q84],
[q85],
[q86],
[q87],
[q88],
[q89],
[q90],
[q91],
[q92]
)
) AS unpvt
ORDER BY
[user_id],
[question_id];
The type of column conflicts with the type of other columns specified in the UNPIVOT list.
Means your column' s data type same but it' s lenght differ.
Example:
q80 VARCHAR(10)
q82 VARCHAR(5)
Solution: #Cast all fields to fix value
CAST(q80 AS VARCHAR(10))
CAST(q82 AS VARCHAR(10))
I have so many long database so I used seq_no in commas separate using more than one sequence store in single column but now I want all sequence in a single column so I am confused how to create this sql result for this.
For example:
TABLE STRUCTURE
SR_NO IS INT ,
SEQ_NO IS VARCHAR(MAX)
SR_NO SEQ_NO
---------------------------------
1 1839073,
2 1850097,1850098,
3 1850099,1850100,1850110
I need to get this result:
SEQ_NO
--------------
1839073
1850097
1850098
1850099
1850100
1850110
Thanks!
declare #t table(Id int,seq varchar(100))
insert into #t (Id,seq) values (1,'1839073,'),(2,'1839073,1850098,'),(3,'1850099,1850100,1850110 ')
;With Cte as (
SELECT A.Id,
Split.a.value('.', 'VARCHAR(100)') AS Seq
FROM
(
SELECT Id,
CAST ('<M>' + REPLACE(seq, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM #t
) AS A CROSS APPLY Data.nodes ('/M') AS Split(a) )
Select ID,Seq from Cte Where Seq > ''
Try splitting it with XML
SELECT SR_NO, t.c.value('.', 'VARCHAR(2000)') COL1
FROM (
SELECT SR_NO, x = CAST('<t>' +
REPLACE(SEQ_NO, ',', '</t><t>') + '</t>' AS XML)
FROM
(values(1,'1839073'),(2, '1850097,1850098'),
(3, '1850099,1850100,1850110')) y(SR_NO, SEQ_NO)
) a
CROSS APPLY x.nodes('/t') t(c)
Result:
SR_NO COL1
1 1839073
2 1850097
2 1850098
3 1850099
3 1850100
3 1850110
You can replace this with your table:
(values (1,'1839073'),(2, '1850097,1850098'),
(3, '1850099,1850100,1850110')) y(SR_NO, SEQ_NO)
This should do it: (Replace YourTableName with your table name)
;WITH CTE(NEW_SEQ_NO, SEQ_NO) as (
SELECT LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO + ',') -1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO + ','), '')
FROM YourTableName
WHERE SEQ_NO <> '' AND SEQ_NO IS NOT NULL
UNION all
SELECT LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO + ',') -1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO + ','), '')
FROM CTE
WHERE SEQ_NO <> '' AND SEQ_NO IS NOT NULL
)
SELECT NEW_SEQ_NO from CTE ORDER BY NEW_SEQ_NO
You can check this topic for more information:
Turning a Comma Separated string into individual rows
I have written the following query after referring Turning a Comma Separated string into individual rows
It will work for you
create table STRUCTURE(SR_NO int, SEQ_NO varchar(max))
insert STRUCTURE select 1, '1839073,'
insert STRUCTURE select 2, '1850097,1850098,'
insert STRUCTURE select 3, '1850099,1850100,1850110'
;with tmp(SR_NO, DataItem, SEQ_NO) as (
select SR_NO, LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO+',')-1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO+','), '')
from STRUCTURE
union all
select SR_NO, LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO+',')-1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO+','), '')
from tmp
where SEQ_NO > ''
)
Select DataItem as SEQ_NO from tmp order by SEQ_NO;
I want to insert value into CAPTURED_DATA_01 table. The value for columns in CAPTURED_DATA_01 table comes from select statements and join.So its little bit complex insert statement.The SUBSCRIPTION_ID should be added from this select query which is running query:
Select * from(
select WF.SUBSCRIPTION_ID
from WF_WORKFLOW#FONIC_RETAIL WF,CAPTURED_DATA_01 CP
where WF.SUBSCRIPTION_ID > CP.SUBSCRIPTION_ID and
WF.SUBSCRIPTION_ID IN
(
select iw.SUBSCRIPTION_ID
from (
SELECT TO_NUMBER(REPLACE(REPLACE(REGEXP_SUBSTR(RESPONSE_XML, '<ax2147:subscriptions xsi:type="ax2127:SubscriptionDTO"><ax2130:id>\d+</ax2130:id>'),
'<ax2147:subscriptions xsi:type="ax2127:SubscriptionDTO"><ax2130:id>', ''), '</ax2130:id>', ''))
AS SUBSCRIPTION_ID ,
CAST(REPLACE(REPLACE(
REGEXP_SUBSTR(REQUEST_XML, '<ns7:orderType>.+</ns7:orderType>'),
'<ns7:orderType>', ''), '</ns7:orderType>', '')
AS VARCHAR(100)) AS order_type,
TO_NUMBER(REPLACE(REPLACE(REGEXP_SUBSTR(RESPONSE_XML, '<ax2147:orderNumber>\d+</ax2147:orderNumber> '),
'<ax2147:orderNumber>', ''), '</ax2147:orderNumber> ', ''))
AS ORDER_NUMBER,
CREATE_DATE
FROM
SOAP_MONITORING#FONIC_RETAIL
where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder'
) iw
where iw.order_type='SELF_REGISTRATION'
)
and WF.NAME='INITIATE_MANDATE'
and WF.STATUS_ID=0 order by wf.START_DATE desc);
Here is the query i tried but getting the error as cannot use LOB locators selected from remote tables,A remote LOB column cannot be referenced,Remove references to LOBs in remote tables. in my subquery where i have cast the SUBSCRIPTION_ID,Order_Number,Order_type
Insert into CAPTURED_DATA_01(SUBSCRIPTION_ID) VALUES
((select WF.SUBSCRIPTION_ID
from WF_WORKFLOW#FONIC_RETAIL WF,CAPTURED_DATA_01 CP
where WF.SUBSCRIPTION_ID > CP.SUBSCRIPTION_ID and
WF.SUBSCRIPTION_ID IN
(
select iw.SUBSCRIPTION_ID
from (
SELECT TO_NUMBER(REPLACE(REPLACE(REGEXP_SUBSTR(RESPONSE_XML, '<ax2147:subscriptions xsi:type="ax2127:SubscriptionDTO"><ax2130:id>\d+</ax2130:id>'),
'<ax2147:subscriptions xsi:type="ax2127:SubscriptionDTO"><ax2130:id>', ''), '</ax2130:id>', ''))
AS SUBSCRIPTION_ID ,
CAST(REPLACE(REPLACE(
REGEXP_SUBSTR(REQUEST_XML, '<ns7:orderType>.+</ns7:orderType>'),
'<ns7:orderType>', ''), '</ns7:orderType>', '')
AS VARCHAR(100)) AS order_type,
TO_NUMBER(REPLACE(REPLACE(REGEXP_SUBSTR(RESPONSE_XML, '<ax2147:orderNumber>\d+</ax2147:orderNumber> '),
'<ax2147:orderNumber>', ''), '</ax2147:orderNumber> ', ''))
AS ORDER_NUMBER,
CREATE_DATE
FROM
SOAP_MONITORING#FONIC_RETAIL
where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder'
) iw
where iw.order_type='SELF_REGISTRATION'
)and WF.NAME='INITIATE_MANDATE'
and WF.STATUS_ID=0))
You can't select multiple columns in a subquery expression, and you aren't selecting enough values anyway. You don't need the extra level of subquery you're adding, you need something like:
Insert into CAPTURED_DATA_01(EVENT_ID,SUBSCRIPTION_ID,EVENT_TIMESTAMP,
ENV_ID,BRAND_ID,BP_ID)
Select '10006',SUBSCRIPTION_ID,START_DATE,
ENV_ID,BRAND_ID,BP_ID -- where are these coming from? should they be literals too?
from(
select WF.SUBSCRIPTION_ID,WF.START_DATE
from WF_WORKFLOW#FONIC_RETAIL WF,CAPTURED_DATA_01 CP
...
It isn't clear where the ENV_ID,BRAND_ID,BP_ID values are coming from though, you might be intending those to be literal values as well; you said they 'should be added using select join' but to what, and how that fits in, isn't obvious.