I have a query which works fine, but I am trying to create a dynamic pivot out of it to get a better end result table.
I found this on SO but I cant relate it to my issue.
The multi-part identifier could not be bound
My working code is this:
DECLARE #RangeDate as date
set #RangeDate = (select distinct cd.weDate from CM_DATA cd where cd.year = 2015 and cd.week = 45)
set #RangeDate = DATEADD(WW, -7, #RangeDate)
DECLARE #SQL as VARCHAR(MAX)
DECLARE #Columns AS VARCHAR(MAX)
SELECT #Columns =
COALESCE(#Columns + ', ','') + QUOTENAME(YearWeek)
FROM
(
SELECT DISTINCT YearWeek
FROM CM_DATA
where weDate >= #RangeDate
) AS B
SET #SQL = '
WITH PivotData AS
(
select cd.Country
, cd.Chain
, cd.YearWeek
, left(sm.Planogram, 2) as planogram
, cd.StoreNo
, cd.UID
, cd.ShortCode
, lp.Family
, lp.ColourShort
, pr.type
, cd.Volume
, ul.WOSOR
from vw_V2_UsrVarLst ul
left join CM_DATA cd on cd.Country = ul.CountryCode and cd.Chain = ul.Chain
left join V2_StoreMaster sm on sm.CountryCode = ul.CountryCode and sm.Chain = ul.Chain and sm.StoreNo = cd.StoreNo and sm.StoreNm = cd.StoreNm and cd.YearWeek between sm.YYYYWW and sm.YYYYWWEND
left join tblProducts pr ON pr.[COUNTRY CODE] = ul.CountryCode and pr.SKU = cd.UID
left join V2_LanguagePack LP ON LP.ShortCode = cd.ShortCode AND lp.Lang = ul.UsrLang
where cd.Country = ul.CountryCode and cd.Chain = ul.Chain and planogram is not null and left(cd.UID, 10) in (select lv.UID from V2_live lv where lv.CountryCode = ul.CountryCode and lv.Chain = ul.Chain and cd.YearWeek between lv.YYYYWW and lv.YYYYWWEND) and cd.weDate >= ' + #RangeDate + ' and sm.Planogram != ''Z''
)
select cd.Country
, cd.Chain
, left(sm.Planogram, 2) as planogram
, cd.StoreNo
, cd.UID
, cd.ShortCode
, lp.Family
, lp.ColourShort
, pr.type
, cd.Volume
, ' + #Columns + '
, ul.WOSOR
FROM PivotData
PIVOT
(
SUM(Volume)
FOR YearWeek
IN(' + #Columns + ')
) AS PivotResult'
EXEC (#SQL)
Can anyone spot what up here
KR
Martin
Try SELECT #SQL instead of your EXEC.
You probably must set the output to Text and use the query options (right click into the query window) to set the max length of text output to a higher value (maximum is 8192).
Than you can paste the result of your dynamic SQL into a new query window and execute this there. You should get a speaking error message and you should even jump to the right place with a double click...
Good luck!
Related
I've inherited a stored proc and I need to add and assign a new variable. The piece of the code that's relevant is:
DECLARE #tableRows VARCHAR(MAX) = '';
SET #tableRows
= N'<tr>
<bgcolor="#6081A0" style="FONT-FAMILY:arial,san-serif;FONT-WEIGHT:normal;color:#6081A0"> :: Resource Scheduler</tr>'
+ N'<tr>
Date: ' + CAST(CONVERT(NVARCHAR, DATENAME(WEEKDAY, #rpt_start_date)) AS VARCHAR(100)) + ' '
+ CAST(CONVERT(NVARCHAR, CAST(#rpt_start_date AS DATE), 100) AS VARCHAR(100)) + '</tr>'
+ '<table border="1" width="100%">'
+ '<tr bgcolor="#DC5E3F" style="FONT-FAMILY:arial,san-serif;FONT-WEIGHT:bold;color:white">'
+ '<td style="text-align:center;vertical-align:middle">START TIME</td>'
+ '<td style="text-align:center;vertical-align:middle">END TIME</td>'
+ '<td style="text-align:center;vertical-align:middle">ROOM</td>'
+ '<td>MEETING TITLE</td>'
+ '<td style="text-align:center;vertical-align:middle">ATTENDEES</td>'
+ '<td>INVITEE' + CHAR(39) + 'S NAME</td><td>HOSTS NAMES</td>'
+ '<td>FOOD SERVICES REQUESTS</td>'
+ '<td>TECHNOLOGY REQUESTS</td>'
+ '<td>OFFICE SERVICES REQUESTS</td></tr>';
SELECT #tableRows
= #tableRows + '<tr ' + 'bgcolor=' +
+ IIF(ROW_NUMBER() OVER (ORDER BY s.[sched_id] DESC) % 2 = 0, '"lightgrey', '"white') + '">'
+ '<td style="text-align:center;vertical-align:middle">' + CAST(CONVERT(NVARCHAR, CAST(srd.[mtg_start_date_local] AS TIME), 100) AS VARCHAR(100)) + '</td>'
+ '<td style="text-align:center;vertical-align:middle">' + CAST(CONVERT(NVARCHAR, CAST(srd.[mtg_end_date_local] AS TIME), 100) AS VARCHAR(100)) + '</td>'
+ '<td style="text-align:center;vertical-align:middle">' + CAST(r.[res_hdr] AS VARCHAR(100)) + '</td>'
+ '<td>' + CAST(s.[sched_desc] AS VARCHAR(100)) + '</td>'
+ '<td style="text-align:center;vertical-align:middle">' + CAST(s.[num_attendees] AS VARCHAR(100)) + '</td>'
+ '<td>' + CAST(ru.[user_name] AS VARCHAR(100)) + '</td>'
+ '<td>' + CAST(hu.[user_name] AS VARCHAR(100)) + '</td>'
+ '<td>' + CAST(dbo.ufn_rsConcatCustomTabServices(#rs_customtab_food,s.[sched_id]) AS VARCHAR(4000)) + '</td>'
+ '<td>' + CAST(dbo.ufn_rsConcatCustomTabServices(#rs_customtab_tech,s.[sched_id]) AS VARCHAR(4000)) + '</td>'
+ '<td>' + CAST(dbo.ufn_rsConcatCustomTabServices(#rs_customtab_os,s.[sched_id]) AS VARCHAR(4000)) + '</td></tr>'
FROM
tbl_sched s WITH (NOLOCK)
INNER JOIN
tbl_sched_res_date srd WITH (NOLOCK)
ON s.[sched_id] = srd.[sched_id]
INNER JOIN
tbl_sched_request sr WITH (NOLOCK)
ON s.[sched_id] = sr.[sched_id]
INNER JOIN
tbl_user ru WITH (NOLOCK)
ON sr.[req_for_user_id] = ru.[user_id]
INNER JOIN
tbl_user hu WITH (NOLOCK)
ON s.create_by = hu.[user_id]
INNER JOIN
tbl_res r WITH (NOLOCK)
ON srd.[res_id] = r.[res_id]
INNER JOIN
tbl_grp g WITH (NOLOCK)
ON r.[grp_id] = g.[grp_id]
INNER JOIN
tbl_loc l WITH (NOLOCK)
ON g.[loc_id] = l.[loc_id]
INNER JOIN
tbl_region rg WITH (NOLOCK)
ON l.[region_id] = rg.[region_id]
LEFT OUTER JOIN -- changed from inner join
tbl_sched_udf_val suv_f WITH (NOLOCK)
ON suv_f.[sched_id] = s.[sched_id]
AND suv_f.[udf_id] =
(
SELECT
u.[udf_id]
FROM
tbl_udf u WITH (NOLOCK)
WHERE
u.[udf_desc] LIKE #rs_customtab_food
)
AND suv_f.[string_value] IS NOT NULL
AND suv_f.[string_value] = 'Yes'
LEFT OUTER JOIN -- changed from inner join
tbl_sched_udf_val suv_t WITH (NOLOCK)
ON suv_t.[sched_id] = s.[sched_id]
AND suv_t.[udf_id] =
(
SELECT
u.[udf_id]
FROM
tbl_udf u WITH (NOLOCK)
WHERE
u.[udf_desc] LIKE #rs_customtab_tech
)
AND suv_t.[string_value] IS NOT NULL
AND suv_t.[string_value] = 'Yes'
LEFT OUTER JOIN -- changed from inner join
tbl_sched_udf_val suv_o WITH (NOLOCK)
ON suv_o.[sched_id] = s.[sched_id]
AND suv_o.[udf_id] =
(
SELECT
u.[udf_id]
FROM
tbl_udf u WITH (NOLOCK)
WHERE
u.[udf_desc] LIKE #rs_customtab_os
)
AND suv_o.[string_value] IS NOT NULL
AND suv_o.[string_value] = 'Yes'
LEFT OUTER JOIN
tbl_sched_res_setup srs WITH (NOLOCK)
ON (
s.[sched_id] = srs.[sched_id]
AND srd.[res_id] = srs.[res_id]
)
LEFT OUTER JOIN
tbl_setup su WITH (NOLOCK)
ON (srs.[setup_id] = su.[setup_id])
WHERE
l.[loc_id] = 13-- 1177 Sixth Ave ( ONLY )
AND s.[deleted_flag] = 0
AND r.[obsolete_flag] = 0
AND g.[obsolete_flag] = 0
AND l.[obsolete_flag] = 0
AND rg.[obsolete_flag] = 0
AND srd.[busy_start_date_local] >= CONVERT(NVARCHAR(20), #rpt_start_date, 112)
AND srd.[busy_start_date_local] < CONVERT(NVARCHAR(20), #rpt_end_date, 112)
ORDER BY
srd.[mtg_start_date_local],
r.[res_hdr];
SELECT #tableRows = #tableRows + '</table>';
As you can see, it's a complicated query. #tableRows is used later on to create the body of an email. Now, I need to get s.sched_desc (see line 7 of SELECT statement) and assign it to a second variable, so that I can use it in the Subject line of the same email. I've tried adding
+ (SELECT #sched_desc = SELECT [sched_desc])
to the bottom of the SELECT statement but it's no good (incorrect syntax near parenthesis). I've also tried
+ '<td>' + (SELECT #sched_desc = CAST(s.[sched_desc] AS VARCHAR(100))) + '</td>'
but again it's expecting another parenthesis. I know I can do this by turning this whole thing into a string and then executing it with sp_executesql (see this example) but I'd prefer to avoid dynamic sql if possible. On the other hand, I really don't want to execute this query twice. Is there another way to get around this?
Your stated task would be more easily accomplished and supported by employing a templating language and some basic string interpolation.
It is not possible to set a variable value within the process of setting another variable's value, but you can do so within the same SELECT.
In your query, add a comma after the closing quote and then set your #sched_desc variable:
SELECT #tableRows = #tableRows + '<tr ' + 'bgcolor=' ... </td></tr>',
#sched_desc = [sched_desc]
FROM tbl_sched s WITH (NOLOCK)
INNER JOIN tbl_sched_res_date srd WITH (NOLOCK)
ON s.[sched_id] = srd.[sched_id]
...
The second variable assignment has access to the same data as the original query, but it will need to be included in whatever selecting process is used to retrieve the value of #tableRows.
As an additional note, I will strongly advise you to identify alternatives to using NOLOCK - here are some links to get you started on that path:
https://www.brentozar.com/archive/2021/11/nolock-is-bad-and-you-probably-shouldnt-use-it/
https://www.brentozar.com/archive/2018/10/using-nolock-heres-how-youll-get-the-wrong-query-results/
https://www.brentozar.com/archive/2016/12/nolock-ever-right-choice/
https://www.brentozar.com/archive/2021/01/but-surely-nolock-is-okay-if-no-ones-changing-data-right/
Paneerakbari is correct that you can assign (and build up) more than one variable in the select. Here is a simplified example that may make things clearer.
DECLARE #TableRows VARCHAR(MAX) = '<table>'
DECLARE #Subject VARCHAR(MAX) = '' -- Only the last value is retained here
SELECT
#TableRows = #TableRows + '<tr><td>' + A.Info + '</td></tr>',
#Subject = A.Title
FROM (
VALUES
(1, 'This', 'This stuff'),
(2, 'That', 'That stuff'),
(3, 'More', 'More stuff')
) A(ID, Title, Info)
ORDER BY A.ID
SET #TableRows = #TableRows + '</table>'
SELECT #Subject, #TableRows
Result:
#Subject = 'More'
#TableRows = '<table><tr><td>This stuff</td></tr><tr><td>That stuff</td></tr><tr><td>More stuff</td></tr></table>'
For readability and maintainability, I often find it useful to move complex intermediate calculations into a CROSS APPLY block, the results of which can then be referenced in the final select.
DECLARE #TableRows VARCHAR(MAX) = '<table>'
DECLARE #Subject VARCHAR(MAX) = '' -- Only the last value is retained here
SELECT
#TableRows = #TableRows + R.ComplexRowConstruction,
#Subject = A.Title
FROM (
VALUES
(1, 'This', 'This stuff'),
(2, 'That', 'That stuff'),
(3, 'More', 'More stuff')
) A(ID, Title, Info)
CROSS APPLY (
SELECT ComplexRowConstruction =
'<tr>'
+ '<td>' + A.Info + '</td>'
+ '</tr>'
) R
ORDER BY A.ID
SET #TableRows = #TableRows + '</table>'
SELECT #Subject, #TableRows
I have a DB2 query as below. I am looking for ways to improve the speed of this one. I have tried visual explain but no indexes were advised by the index advisor. Can somebody have a look at this and advise if something can be done?
There is
CREATE OR REPLACE VIEW PSCMPORDVW
AS
WITH INPROGRESS AS
(
SELECT
DIODR#
, DIDISP
, DIUNIT
, DISTST
, DIAPRV
, DIETAD
, DITRLR AS TRAILER_ID
, DIDR1
, DIETAT
FROM
LOAD
WHERE
DIETAD <> 0
AND DIETAT <> '0000'
ORDER BY
1
)
, STOPGROUP AS
(
SELECT
SOORD STOPORDER
, COUNT(*) STOPSREMAIN
, MIN(SOSTP#) NEXTSTOP
, MAX(SOAPPR) APPTREQ
FROM
STOPOFF
INNER JOIN
INPROGRESS
ON
DIODR# = SOORD
WHERE
SOARDT = 0
GROUP BY
SOORD
ORDER BY
1
)
, STOPAPPTS AS
(
SELECT
SOORD APPTORDER
, SOCUST STOPCUST
, SOEDA ETADATE
, SOETA ETATIME
, SOADT1 EARLYDATE
, SOATM1 EARLYTIME
, SOADT2 LATEDATE
, SOATM2 LATETIME
, SOCTYC NEXTCITY
, SOSTP# APPTSTOP
, SOST NEXTSTATE
FROM
STOPOFF
INNER JOIN
STOPGROUP
ON
STOPORDER = SOORD
AND NEXTSTOP = SOSTP#
)
SELECT
ORDER_NUMBER
, SHIPPER_ID
, SHIPPER_NAME
, SHIPPER_ADDRESS_1
, SHIPPER_ADDRESS_2
, SHIPPER_CITY
, SHIPPER_ST
, SHIPPER_ZIP
, SHIPPER_ZIP_EXT
, LOAD_AT_ID
, LOAD_AT_NAME
, LOAD_AT_ADDRESS_1
, LOAD_AT_ADDRESS_2
, LOAD_AT_CITY
, LOAD_AT_ST
, LOAD_AT_ZIP
, LOAD_AT_ZIP_EXT
, LOAD_AT_LATITUDE
, LOAD_AT_LONGITUDE
, EARLY_PU_DATE_TIME
, LATE_PU_DATE_TIME
, EARLY_DELV_DATE_TIME
, EST_REVENUE
, ORDER_DIV
, CONSIGNEE_ID
, CONSIGNEE_NAME
, CONSIGNEE_ADDRESS_1
, CONSIGNEE_ADDRESS_2
, CONSIGNEE_CITY
, CONSIGNEE_ST
, CONSIGNEE_ZIP
, CONSIGNEE_ZIP_EXT
, CONSIGNEE_LATITUDE
, CONSIGNEE_LONGITUDE
, TRAILER_TYPE
, ORDER_MESSAGE
, ADDITIONAL_STOPS
, CMDTY_CODE
, CMDTY_DESCRIPTION
, ORDER_MILES
, ORDER_WGT
, ORIGIN_CITY_CODE
, ORIGIN_CITY
, ORIGIN_ST
, DEST_CITY_CODE
, DEST_CITY_NAME
, DEST_ST
, PICK_UP_AREA
, PLAN_INFO
, NUMBER_LDS
, NUMBER_DISP
, SHIP_DATE_TIME
, NEW_PICKUP_AREA
, EQUIPMENT_NUMBER
, APPT_REQ
, APPT_MADE
, PRE_T_SEQ
, PRE_T_AREA
, LOAD_DISPATCHED
, CUST_SERV_REP
, NEGOTIATIONS
,
(
CASE
WHEN UNUNIT IS NOT NULL
THEN UNUNIT
ELSE ' '
END
)
UNIT_DISPATCHED
,
(
CASE
WHEN UNSUPR IS NOT NULL
THEN UNSUPR
ELSE ' '
END
)
DRIVER_MGR_CODE
, COALESCE(SUPNAM, ' ') DRIVER_MGR_NAME
,
(
CASE
WHEN UNFMGR IS NOT NULL
THEN UNFMGR
ELSE ' '
END
)
FLEET_MGR_CODE
, COALESCE(FLTNAM, ' ') FLEET_MGR_NAME
,
(
CASE
WHEN UNTRL1 IS NOT NULL
THEN UNTRL1
ELSE ' '
END
)
TRAILER_ID
, DIDISP DISPATCH_NUMBER
, (COALESCE(BCMCNEW, ' ')) FED_MC_ID
, DIUNIT DISPATCHED_UNIT
, CASE
WHEN UNETAD <> 0
AND UNETAT = ''
THEN CVTDATETIM(CHAR(UNETAD),'0000', (
SELECT
SUBSTR(DATA_AREA_VALUE, 1109, 2) AS TIMEZONE
FROM
TABLE(QSYS2.DATA_AREA_INFO('COMPAN', '*LIBL'))
)
)
WHEN UNETAD <> 0
THEN CVTDATETIM(CHAR(UNETAD),UNETAT, (
SELECT
SUBSTR(DATA_AREA_VALUE, 1109, 2) AS TIMEZONE
FROM
TABLE(QSYS2.DATA_AREA_INFO('COMPAN', '*LIBL'))
)
)
WHEN UNETAD = 0
THEN '0000-00-00T00:00:00-00:00'
END AS ETA_DATE_TIME
, NEXTSTOP
, CASE
WHEN SOARDT <> 0
AND SOARTM = ''
THEN CVTDATETIM(CHAR(SOARDT),'0000', (
SELECT
SUBSTR(DATA_AREA_VALUE, 1109, 2) AS TIMEZONE
FROM
TABLE(QSYS2.DATA_AREA_INFO('COMPAN', '*LIBL'))
)
)
WHEN SOARDT <> 0
THEN CVTDATETIM(CHAR(SOARDT),SOARTM, (
SELECT
SUBSTR(DATA_AREA_VALUE, 1109, 2) AS TIMEZONE
FROM
TABLE(QSYS2.DATA_AREA_INFO('COMPAN', '*LIBL'))
)
)
WHEN SOARDT = 0
THEN '0000-00-00T00:00:00-00:00'
END AS STOP_ARRIVAL_DATE_TIME
, CASE
WHEN SOLUDT <> 0
AND SOLUTM = ''
THEN CVTDATETIM(CHAR(SOLUDT),'0000', (
SELECT
SUBSTR(DATA_AREA_VALUE, 1109, 2) AS TIMEZONE
FROM
TABLE(QSYS2.DATA_AREA_INFO('COMPAN', '*LIBL'))
)
)
WHEN SOLUDT <> 0
THEN CVTDATETIM(CHAR(SOLUDT),SOLUTM, (
SELECT
SUBSTR(DATA_AREA_VALUE, 1109, 2) AS TIMEZONE
FROM
TABLE(QSYS2.DATA_AREA_INFO('COMPAN', '*LIBL'))
)
)
WHEN SOLUDT = 0
THEN '0000-00-00T00:00:00-00:00'
END AS STOP_DEPART_DATE_TIME
, ORBAMT ORDER_INV_AMT
, ORARST AR_STATUS_FLAG
, DISTST SETTLEMENT_FLAG
, DIAPRV APPROVED_FOR_PAY
, BCCARR CARRIER_CODE
, BCNAME CARRIER_NAME
, BCADDR CARRIER_ADDRESS_1
, BCADR2 CARRIER_ADDRESS_2
, BCCITY CARRIER_CITY
, BCST CARRIER_ST
, BCZIP CARRIER_ZIP
FROM
INPROGRESS
INNER JOIN
PSMAINORVW A
ON
DIODR# = ORDER_NUMBER
AND DIDISP = NUMBER_DISP
AND
(
SUBSTR(ORDER_NUMBER, 1, 2) <> 'DH'
AND SUBSTR(ORDER_NUMBER, 1, 1) <> 'M'
)
LEFT OUTER JOIN
STOPOFF
ON
DIODR# = SOORD
AND SOSTP# = 90
LEFT OUTER JOIN
LMCARR
ON
DIUNIT = BCCARR
LEFT OUTER JOIN
MMILES
ON
MMORD# = DIODR#
AND MMRECTYPE = 'D'
AND MMDSP# = DIDISP
EXCEPTION JOIN
ORDBILL B
ON
B.ORODR# = DIODR#
AND B.ORSEQ = ' '
AND ORARST = '1'
LEFT OUTER JOIN
STOPGROUP
ON
STOPORDER = DIODR#
LEFT OUTER JOIN
STOPAPPTS
ON
APPTORDER = STOPORDER
AND APPTSTOP = NEXTSTOP
LEFT OUTER JOIN
UNITS
ON
UNUNIT = DIUNIT
AND UNORD# = ORDER_NUMBER
LEFT OUTER JOIN
SUPMAST
ON
SUPCDE = UNSUPR
LEFT OUTER JOIN
FLTMAST
ON
UNFMGR = FLTCDE
WHERE
DIETAD <> 0
AND DIETAT <> '0000'
RCDFMT PSCMPORDVW ;
I suspect that the below part might be slowing it up. Can someone advise what can be done here?
STOPGROUP AS
(
SELECT
SOORD STOPORDER
, COUNT(*) STOPSREMAIN
, MIN(SOSTP#) NEXTSTOP
, MAX(SOAPPR) APPTREQ
FROM
STOPOFF
INNER JOIN
INPROGRESS
ON
DIODR# = SOORD
WHERE
SOARDT = 0
GROUP BY
SOORD
ORDER BY
1
)
Even though Visual Explain (VE) doesn't advise any indexes ... it can still be used to see how long various parts of your query are taking.
If the
SELECT
SOORD STOPORDER
, COUNT(*) STOPSREMAIN
, MIN(SOSTP#) NEXTSTOP
, MAX(SOAPPR) APPTREQ
Turns out to really be any issue, I'd look at using an Encoded Vector Index (EVI) with aggregate values to speed that up.
I'd suggest breaking it down and building back up while using VE to see where the issues lie.
The only magic wand I might suggest is putting code into a user defined table function (UDTF); assuming you currently plan to use the view like so:
select *
from myview
where something = 'somevalue';
A UDTF would allow for you to explicitly push the selection into the query
select *
from table ( myudtf('somevalue'));
$query = "select (select count(a.serial_no) from tra2 a where a.model_no = ".$id." and a.flag = cast(3 as character varying) + (select count(a.serial_no) from stk a where a.model_no = ".$id." and a.trans_id is NULL)as qty)";
$result = $this->db->query($query);
return $result->result();
When i run the query
ERROR: syntax error at or near "as"
LINE 1: ...ck a where a.model_no = K258 and a.trans_id is NULL)as qty)
Add '' (quotes) on your WHERE clauses. I guess the data type is VARCHAR so you have to use quotes in your query
Like this
.... WHERE a.model_no = '" . $id . "' AND ...
The end of the quest must be:
...a.trans_id is NULL)) as qty"
Currently You have some like this
select (select 1 + 2 as qty)
but You want
select (select 1 + 2) as qty
This is my code
Select #pos = Pos, #ptsReputacion = isnull(AA.PtsReputacion,0)
From
(Select
ROW_NUMBER() OVER (ORDER BY #ptsReputacion DESC) AS Pos
, USUARIO.CodUsuario
, PtsReputacion = (Select isnull(sum(Puntos),0) as Puntos
From USUARIO_RANKING_INTERES
Where USUARIO_RANKING_INTERES.CodUsuario = #codUsuario)
, USUARIO.CantIntentos as Intentos
, USUARIO.CantAciertos as Aciertos
, USUARIO.CantFallos as Fallos
, isnull(USUARIO.PG,0) as PG
, isnull(USUARIO.PE,0) as PE
, isnull(USUARIO.PP,0) as PP
, isnull(USUARIO.TiempoTotal,0) as TiempoTotal
From USUARIO) AA
Where AA.CodUsuario = #codUsuario
But it doesn't works because the Pos field has an other value. For example, it gives 2 instead 1.
I want to know how to get the row position number one by one ordered by a variable (because the field is a subquery).
It looks like you really want to do something like the below. I'm using CTEs because that makes it easier to read.
WITH BaseQuery AS
(
SELECT
U.CodUsuario
, PtsReputacion = (Select isnull(sum(Puntos),0) as Puntos
From USUARIO_RANKING_INTERES
Where USUARIO_RANKING_INTERES.CodUsuario = U.CodUsuario)
, USUARIO.CantIntentos as Intentos
, USUARIO.CantAciertos as Aciertos
, USUARIO.CantFallos as Fallos
, isnull(USUARIO.PG,0) as PG
, isnull(USUARIO.PE,0) as PE
, isnull(USUARIO.PP,0) as PP
, isnull(USUARIO.TiempoTotal,0) as TiempoTotal
FROM USUARIO U
),
RNQuery AS
(
SELECT
*
, ROW_NUMBER() OVER (ORDER BY PtsReputacion DESC) AS Pos
FROM
BaseQuery
)
SELECT
#pos = Pos
, #ptsReputacion = isnull(AA.PtsReputacion,0)
FROM
RNQuery AS AA
WHERE
AA.CodUsuario = #codUsuario
I have two tables:
Unit:
UnitId int PK
Title varchar
UnitOption:
UnitOptionId int PK
UnitId int FK
Title varchar
Quote:
QuoteId int PK
UnitOptionId int FK
Title varchar
I want to create a scalar UDF that takes a QuoteId param and returns a varchar that contains the following description (pseudu):
Quote.Title + '-' + Unit.Title + '-' + Unit.UnitId +
/* Here is where my question is:
If there are more than 1 UnitOption under this Unit, then
return '-' + the UnitOption number under this Unit
(i.e.) if under this Unit, there are 3 UnitOption with IDs 13, 17, 55
under the unit, and the current Quote.UnitOptionId is the 17 one,
it should return 2.
Which means I want to retrieve an ID of this row in the group.
Else
return ''
*/
If you're using SQL 2005 or later and I've interpreted your question correctly, you should be able to adapt the following into your function.
WITH [UnitExt] AS
(
SELECT
[Unit].[UnitId],
[Unit].[Title],
COUNT(*) AS [Count]
FROM [Unit]
INNER JOIN [UnitOption] ON [UnitOption].[UnitId] = [Unit].[UnitId]
GROUP BY
[Unit].[UnitId],
[Unit].[Title]
)
SELECT
[Quote].[Title] + '-' + [UnitExt].[Title] + '-' + [UnitExt].[UnitId] +
CASE
WHEN [UnitExt].[Count] > 1 THEN '-' +
CAST([UnitOption].[UnitOptionId] AS varchar(max))
ELSE ''
END
FROM [Quote]
INNER JOIN [UnitOption] ON [UnitOption].[UnitOptionId] =
[Quote].[UnitOptionId]
INNER JOIN [UnitExt] ON [UnitExt].[UnitId] = [UnitOption].[UnitId]
WHERE [Quote].[QuoteId] = #QuoteId
Something like this should do it.
SELECT DISTINCT Quote.Title +
' - ' + Unit.Title +
' - ' + Unit.UnitId +
CASE
WHEN COUNT(*) OVER(PARTITION BY Quote.Id) > 0
THEN
' - ' + CAST(ROW_NUMBER() OVER (PARTITION BY Quote.Id ORDER BY Quote.UnitOptionId) AS varchar)
ELSE
''
END
FROM Quote
JOIN UnitOption ON UnitOption.Id = Quote.UnitOptionId
JOIN Unit ON Unit.Id = UnitOption.UnitId
WHERE Quote.Id = #QuoteId
CREATE FUNCTION ufnGetDescription
(#QuoteID INT)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #RetVal VARCHAR(MAX);
WITH CurRow
AS (SELECT quote.title + '- ' + unit.title AS start,
u.unitid,
quoteid,
uo.unitoptionid
FROM quote
INNER JOIN unitoption uo
ON quote.unitoptionid = uo.unitoptionid
INNER JOIN unit
ON uo.unitid = unit.unitid
WHERE quote.quoteid = #QuoteID),
AllUnits
AS (SELECT u.unitid,
uo.unitoptionid,
Row_number()
OVER(PARTITION BY u.unitid ORDER BY uo.unitoptionid) AS NUMBER,
Count(* )
OVER(PARTITION BY u.unitid ) AS cntUnits
FROM unit
INNER JOIN unionoption uo
ON unit.unitid = uo.unitid
WHERE u.unitid IN (SELECT unitid
FROM CurRow))
SELECT #RetVal = CASE
WHEN a.cntUnits = 1 THEN ''
ELSE r.start + '-' + Cast(NUMBER AS VARCHAR(max))
END
FROM AllUnits a
INNER JOIN CurRow r
ON a.unitoptionid = r.unitoptionid
RETURN #RetVal
END