I have SQL query
; with cte as
(
SELECT
PARSENAME(REPLACE(replace(replace(replace(replace(dbo.IDENTITY_MAP.Name, 'My Company\', ''), '-VLAN2', ''), '.VLAN2\', ''), '.Instr\', '') , '\' , '.'), 1) as "Site",
Count (CASE
WHEN dbo.SEM_AGENT.AGENT_VERSION LIKE '11.%' THEN 1
END) AS 'SEP-11',
Count (CASE
WHEN dbo.SEM_AGENT.AGENT_VERSION LIKE '12.%' THEN 1
END) AS 'SEP-12',
FROM
dbo.sem_computer
INNER JOIN
[dbo].[V_SEM_COMPUTER] ON [dbo].[V_SEM_COMPUTER].COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
WHERE
dbo.IDENTITY_MAP.Name NOT LIKE '%Servers%'
GROUP BY
PARSENAME(REPLACE(replace(replace(replace(replace(dbo.IDENTITY_MAP.Name,'My Company\',''),'-VLAN2',''),'.VLAN2\',''),'.Instr\','') , '\' , '.'),1)
)
select *
from cte
join SEPM_site ss on cte.Site = ss.Site
That gives output I am looking for ------ almost i.e.
Site SEP-11 SEP-12 Rackcode Circuit Site
I only need one column for Site.
I tried recreating a temporary table with the columns, and dropping it, i.e.
; with cte as (SELECT ...)
select * into temptable
from cte
join SEPM_site ss
on cte.Site = ss.Site
alter table temptable
drop column cte.Site
select * from temptable
drop table temptable
But I get error
Incorrect syntax near '.'
And if I don't specify which table Site is from, I get error,
Column names in each table must be unique. Column name 'Site' in table 'temptable' is specified more than once.
But that's why I am trying to remove duplicate column!
Thanks!
Just specify the columns you want in your select statement:
select cte.Site, cte.[SEP-11], cte.[SEP-12], ss.Rackcode, ss.Circuit
from cte
join SEPM_site ss
on cte.Site = ss.Site
You can also select all columns in cte and just the ones you want in ss:
select cte.*, ss.Rackcode, ss.Circuit
from cte
join SEPM_site ss
on cte.Site = ss.Site
Related
I am using the following query to gather some information about each ProductId - note that a ProductId can contain several records in the dbo.Sales table:
SELECT
c.ProductId,
COUNT(*) as NumberOfRecords,
(SELECT
(ISNULL(NULLIF(c.Text, ''), 'FALSE'))) as TextFieldHasData
FROM dbo.Sales c
JOIN dbo.Sources s
ON c.ProductId = s.ProductId
AND s.SourceStatusId in (1,2)
GROUP BY c.ProductId, c.Status, s.SourceStatusId, c.Text
ORDER BY c.ProductId
I need to tweak the ISNULL part of the query, and I'm having trouble with the syntax; what I actually need to do is first check the NumberofRecordscount - if the the NumberofRecords count for a given result record is greater than 1, then the TextFieldHadData field for that record should just say 'N/A'. But, if the NumberofRecordscount for a given result record = 1, then it should check whether the c.Text field is NULL or blank. If it is NULL or Blank, the TextFieldHasData field would say 'FALSE.' If it is not NULL or blank, the TextFieldHasData field would say 'TRUE.'
Looking at your code, perhaps you are looking for something like the following (where you would be grouping up to ProductId level):
SELECT
c.ProductId
, COUNT(*) as NumberOfRecords
,
CASE
WHEN COUNT(*) > 1
THEN 'N/A'
ELSE
CASE
WHEN SUM(CASE WHEN ISNULL(c.Text, '') = '' THEN 0 ELSE 1 END) > 0
THEN 'TRUE'
ELSE 'FALSE'
END
END TextFieldHasData
FROM
dbo.Sales c
JOIN dbo.Sources s ON
c.ProductId = s.ProductId
AND s.SourceStatusId in (1, 2)
GROUP BY c.ProductId
ORDER BY c.ProductId
You can use the query:
I can not validate it as I don't have these tables, but it should work, unless you find a minor syntax error.
The idea is to use "case when ..." sql function
select v.productid,v.NumberOfRecords,
case
when v.NumberOfRecords>1 then 'N/A'
when v.NumberOfRecords=1 and isnull(v.TextFieldHasData,'') ='' then 'FALSE'
else 'TRUE' end [textfieldhasdata]
from(
SELECT
c.ProductId,
COUNT(*) as NumberOfRecords,
(SELECT
(ISNULL(NULLIF(c.Text, ''), 'FALSE'))) as TextFieldHasData
FROM dbo.Sales c
JOIN dbo.Sources s
ON c.ProductId = s.ProductId
AND s.SourceStatusId in (1,2)
GROUP BY c.ProductId, c.Status, s.SourceStatusId, c.Text) v
ORDER BY ProductId
I have the following code:
IF (OBJECT_ID('tempdb..#Data') IS NOT NULL)
BEGIN
DROP TABLE #Data
END
SELECT
t.Name, x.Time, x.Date, x.Total,
xo.DrvCommTotal, x.Name2, x.Street, x.Zip,
r.Route1
INTO
#Data
FROM
table1 xo WITH(NOLOCK)
LEFT JOIN
Table2 t WITH(NOLOCK) ON t.ID = x.ID
LEFT JOIN
Route1 r ON r.RouteID = x.RouteID
WHERE
x.Client = 1
AND x.Date = '9/13/2018'
GROUP BY
t.Name, x.Time, x.Date, x.Total, xo.DrvCommTotal, x.Name2,
x.Street, x.Zip, r.Route1
ORDER BY
Route1
SELECT DISTINCT
F.*, F2.NumOrders
FROM
#Data F
LEFT JOIN
(SELECT
Route1, COUNT(*) NumOrders
FROM
#Data
GROUP BY
Route1) F2 ON F2.Route1 = F.Route1
LEFT OUTER JOIN
(SELECT
Street + ',' + Zip Stops, Time, RouteN1
FROM
#Data
GROUP BY
RouteNo1, street, Zip) F3 ON F3.Route1 = F.Route1
WHERE
F.Route1 IS NOT NULL
ORDER BY
F.Route1
and it provides me with a list of routes and stops. The column NumOrders lets me know how many orders are on each route. I need the stops to become individual columns I will label Stop1, Stop2, etc. so that each route is only one row and all the information is contained on the row for one route.
I'm currently using the temp table because the data is so large. I can play with my SELECT statement without having to re-run the entire code.
How do I move the stops for each route into columns?
Hum.. Not quite sure I understand the question but it sounds that you want to pivot the data so that the routes break into columns. If so, I would use a sql Pivot. Here is an example from the documentation:
USE AdventureWorks2014;
GO
SELECT VendorID, [250] AS Emp1, [251] AS Emp2, [256] AS Emp3, [257] AS Emp4, [260] AS Emp5
FROM
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [250], [251], [256], [257], [260] )
) AS pvt
ORDER BY pvt.VendorID;
Also, here is the link to how to use pivot: https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-2017
Since you already have all the data in your temp table, you could pivot that on the way out.
Combining some examples, I came up with the following query (fields and table names have been anonymised soI hope I didn't insert typos).
UPDATE destinationTable
SET destinationField = t2.value
FROM destinationTable t1
CROSS APPLY (
SELECT TOP 1 'SomeRequiredPrefix ' + sourceField as value
FROM #sourceTable
WHERE sourceField <> ''
ORDER BY NEWID()
) t2
Problem
Currently, all records get the same value into destinationField , value needs to be random and different. I'm probably missing something here.
Here's a possible solution. Using CTE's assign row numbers to both tables based on random order. Join the tables together using that rownumber and update the rows accordingly.
;WITH
dt AS
(SELECT *, ROW_NUMBER() OVER (ORDER BY NEWID()) AS RowNum
FROM dbo.destinationtable),
st AS
(SELECT *, ROW_NUMBER() OVER (ORDER BY NEWID()) AS RowNum
FROM dbo.#sourcetable)
UPDATE dt
SET dt.destinationfield = 'SomeRequiredPrefix ' + st.sourcefield
FROM dt
JOIN st ON dt.RowNum = st.RowNum
UPDATED SOLUTION
I used CROSS JOIN to get all possibilities since you have less rows in source table. Then assign random rownumbers and only take 1 row for each destination field.
;WITH cte
AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY destinationfield ORDER BY NEWID()) AS Rownum
FROM destinationtable
CROSS JOIN #sourcetable
WHERE sourcefield <> ''
)
UPDATE cte
SET cte.destinationfield = 'SomeRequiredPrefix ' + sourcefield
WHERE cte.Rownum = 1
SELECT * FROM dbo.destinationtable
Is it possible to make a count of rows (I am using a view) with a resultset of a subquery?
Assuming I have
Table1
t1id
Table2
id, t1id_Parent, t1id_Child
Table3
t1id
I query for
select
t1.t1id as id,
stuff((select ', ' + CAST(CASE WHEN t2.t1id_Child is not null THEN t2.t1id_Child ELSE '0' END AS varchar) from Table1 t where t.t1id_Parent = t1.t1id for xml path('')),1,2,'') as ids
FROM
Table1 as t1
LEFT OUTER JOIN
Table1 AS t2 ON t1.t1id = t2.t1id_Parent
So I have the needed ids combined into a string that looks like this '1,2,5,9' in the column named "ids" that is working correctly however what I need to do now is have this query
select
t1.t1id as id,
stuff((select ', ' + CAST(CASE WHEN t2.t1id_Child is not null THEN t2.t1id_Child ELSE '0' END AS varchar) from Table1 t where t.t1id_Parent = t1.t1id for xml path('')),1,2,'') as ids
FROM
Table1 as t1
LEFT OUTER JOIN
Table2 AS t2 ON t2.t1id_Parent = t1.t1id
LEFT OUTER JOIN
(select count(t1id) as rows_count, t1id
from Table3
group by t1id) as docs ON docs.t1id in (ids)
to retrieve the row count from the 3rd table using the temporary column however I am getting an error of Invalid column name 'ids'
Is this possible or do I need to first run that query and then go back and run a new one for the count of the third table?
The result I need is
Table1.t1id, count(Table3.t1id)
Table3.t1id comes from Table1.t1id and all Table2.t1id_Child relation through Table1.t1id = Table2.t1id_Parent
I guess not possible, but got it partially working with CTE, I am now getting the list of say I have this '15673,15690,90987,45058' I can then do the query for the third column but getting the error
WITH items AS
(
select
a.ItemID,
stuff(
(select ',' +
CAST(
CASE WHEN b.[ChildItemID] is not null
THEN b.[ChildItemID] ELSE 0 END AS varchar)
from Table2 t2
where t2.[ParentItemID] = a.ItemID
for xml path('')
),1,2,'')
select
items.*,
docs.docs_count
from items
LEFT OUTER JOIN (
select count([DocID]) as docs_count from Table3
group by DocID
) as docs ON docs.ItemID in (items.ItemID)
Conversion failed when converting the nvarchar value '15673,' to data type int.
Note that the issue is not concatenating, I am getting the result expected there, a comma separated list of values, the issue comes when I try to use the comma separated values in "as docs ON docs.ItemID in (items.ItemIDs)"
I have pretty basic table schema.
Table A
TEMPLATE_ID TEMPLATE_NAME
Table A has the following rows
1 Procs
2 Letter
3 Retire
4 Anniversary
5 Greet
6 Event
7 Meeting
8... etc.
Table B
TEMPLATE_ID VALUE
Table B has 100K+ rows with TEMPLATE_ID connecting the two tables.
Now the execs want a sample of 20 records of types 1-5 from table A. I could do something basic...which is about my speed when it comes to TSQL.
SELECT TOP(20) B.VALUE FROM TableB
JOIN TableA ON
B.TEMPLATE_ID = A.TEMPLATE_ID
AND TableA.TEMPLATE_NAME IN ('Procs', 'Letter'...)
But that isn't quite right as I end up with 20 rows...in other words I was expecting 100 rows. 20 for each.
Is this one of those areas where partition could be used. I can see how I would break TableB into partitions for each template (tableA) but I'm not sure how I would limit it to 20 rows.
OK so I could just cut and past into Excel 20 rows from each partition...I could also write 5 very basic queries...but this is kind of an academice...improve my knowledge pursuit.
So to clarify. 20 records from each of the first r template types.
TIA
you can use ROW_NUMBER and partition the data based on the template_name and return only 20 from each partition
SELECT * FROM
(
SELECT B.VALUE,
ROW_NUMBER() OVER ( PARTITION BY TableA.TEMPLATE_NAME ORDER BY ( select NULL)) as seq
FROM
TableB
JOIN TableA ON
B.TEMPLATE_ID = A.TEMPLATE_ID
) T
where T.seq <=20
order by B.VALUE
Could you try?
SELECT B.VALUE
FROM
(
SELECT TEMPLATE_ID,VALUE, DENSE_RANK ( ) OVER (PARTITION BY TEMPLATE_ID ORDER BY VALUE DESC) AS RANK_NO
FROM TABLE_B
) B INNER JOIN TABLE_A A ON (A.TEMPLATE_ID = B.TEMPLATE_ID)
WHERE A.TEMPLATE_NAME IN ('Procs', 'Letter'...)
AND B.RANK_NO <= 20
;
You use a ranking function. You first partition your data, order each partition and apply the ranking function:
select seq = row_number() over (
partition by table_catalog , table_schema , table_name
order by column_name
) ,
*
from information_schema.COLUMNS
The above code partitions the rows in information_schame.COLUMNS on the fully-qualified table/view name to which they belong. Each partition is then ordered alphabetically and given a row_number().
That then gets wrapped in another select which makes use of it. This code pulls the first 3 columns for each table in the system based on column and provides some information about it:
select t.table_name ,
t.table_schema ,
t.table_name ,
t.table_type ,
c.seq ,
c.ordinal_position ,
c.COLUMN_NAME ,
data_type = c.data_type + coalesce('('+convert(varchar,c.character_maximum_length)+')','')
+ case c.is_nullable when 'yes' then ' is null' else ' is not null' end
from information_schema.tables t
join ( select seq = row_number() over (
partition by table_catalog , table_schema , table_name
order by column_name
) ,
*
from information_schema.COLUMNS
) c on c.table_catalog = t.table_catalog
and c.table_schema = t.table_schema
and c.table_name = t.table_name
where c.seq <= 3
order by t.table_catalog ,
t.table_schema ,
t.table_name ,
c.seq
SELECT * FROM
( SELECT B.VALUE, TableA.TEMPLATE_NAME
ROW_NUMBER() OVER ( PARTITION BY A.TEMPLATE_ID ORDER BY NEWID() ) as row
FROM TableB
JOIN TableA
ON A.TEMPLATE_ID = B.TEMPLATE_ID
AND A.TEMPLATE_ID <= 5
) T
where T.row <= 20
order by B.VALUE