How do I do this query in linq? All the tables already are list of objects.
This query give points to entities named "Empresas" (Companies) that fills the "Palavras" (Words) criterias.
select x.empresaid, sum(x.pontos)
from (
select a.empresaid, sum(1) as Pontos
from empresa a
inner join Palavras b on a.nome like '%' + b.Palavra + '%'
group by a.empresaid
union all
select a.empresaid, sum(case when c.estabelecimento is null then 0 else 1 end) as Pontos
from empresa a
left join estabelecimentoempresa b on b.empresaid = a.empresaid
left join estabelecimento c on c.estabelecimentoid = b.estabelecimentoid
left join Palavras d on c.estabelecimento like '%' + d.Palavra + '%'
group by a.empresaid
union all
select a.empresaid, sum(case when c.Cozinha is null then 0 else 1 end) as Pontos
from empresa a
left join Cozinhaempresa b on b.empresaid = a.empresaid
left join Cozinha c on c.Cozinhaid = b.Cozinhaid
left join Palavras d on c.Cozinha like '%' + d.Palavra + '%'
group by a.empresaid
) x
group by x.empresaid
order by sum(x.pontos) desc, x.empresaid
I don't think you would be able convert as it is from SQL to LINQ. You could still try this tool that convert SQL to LINQ syntax:
http://www.sqltolinq.com/
The preferable approach is to understand and write the LINQ syntax on your own.
Related
I have a problem I want to get all of the DISTINCT CLIENTIDs in my LCMINV table in which the CLIENTID is in LAAPPL's CLIENTID and LACOBORW's COBORWID and also the APPLICATION STATUS is either 'PEN' OR 'REC'.
Here is my table:
++++++++++++++++++++++++++++++++++++++++++++
+ LAAPPL + LACOBORW + LCMINV +
++++++++++++++++++++++++++++++++++++++++++++
+ CLIENTID + APPLNO + CLIENTID +
+ APPLNO + COBORWID + +
+ STATUS + + +
++++++++++++++++++++++++++++++++++++++++++++
Here is my SQL Query I've done so far:
SELECT DISTINCT(CLIENTID)
FROM LCMINV
WHERE CLIENTID
IN (SELECT CLIENTID, COBORWID
FROM LAAPPL
LEFT OUTER JOIN LACOBORW ON LACOBORW.APPLNO = LAAPPL.APPLNO
WHERE STATUS = 'PEN' OR STATUS = 'REC')
Can it be done in one query or do I need separate queries? I tried my query above an I am getting an error "Too many values"
I would probably use a CTE to break the query up into smaller parts, and then use INNER JOINs to combine the tables. Since You query LAAPPL, I put both columns used into a single subquery, and then join on each column in the next CTE.
It would look something like this:
WITH CTE_LAAPPL AS
(
SELECT
CLIENTID
,APPLNO
FROM LAAPPL
WHERE STATUS IN ('PEN','REC')
)
,CLIENTIDs AS
(
SELECT DISTINCT
l.COBORWID AS CLIENTID
FROM CTE_LAAPPL c
INNER JOIN LACOBORW l ON l.APPLNO = c.APPLNO
UNION
SELECT DISTINCT
l.CLIENTID
FROM CTE_LAAPPL c
INNER JOIN LCMINV l ON l.CLIENTID = c.CLIENTID
)
SELECT
c.CLIENTID
,c.NAME
FROM LCCLIENT c
INNER JOIN CLIENTIDs i ON i.CLIENTID = c.CLIENTID
ORDER BY NAME
I think you just want:
SELECT DISTINCT i.CLIENTID
FROM LCMINV i
WHERE i.CLIENTID IN (SELECT a.CLIENTID
FROM LAAPPL a JOIN
LACOBORW c
ON c.APPLNO = a.APPLNO
WHERE a.STATUS IN ('PEN', 'REC')
);
I'm not really sure why you are joining in LACOBORW. You can probably remove that logic.
I would recommend left joins to get the data you need. Unfortunately, your question 3 does not seem to fit your model because your LCMINV table does not seem to have an id that matches to another table and I cannot understand where LCMINV.CLIENTID should be related to in another context. This works in MSSQL - cannot be sure about Oracle.
--this statement will give you all the names that have a status in the where clause
--you will receive NULL if there is no Co-BorrowerID
select
a.name
, b.applno
, b.status
, c.coborwid
from
lcclient a left join
laapl b on a.clientid = b.clientid left join
lacoborw c on b.applno = c.applno
where
b.status in ('PEN', 'REC')
order by
a.name
I have this 2 tables
Items
ID Type ClientID
========================
1 0 123
2 0 123
Texts
ItemID Language Text
================================
1 Eng Hi there!
1 Spa Holla!
2 Eng bye!
2 Spa bye in Spanish!
In my final result I wat the SQL to return me this table
ID Type Eng Spa
================================
1 0 Hi there! Holla!
2 0 Bye! bye in Spanish!
I tried to create this statement:
SELECT DISTINCT I.ID ,I.Type,
(SELECT T.Text WHERE D.Language='Eng') AS 'Eng',
(SELECT T.Text WHERE D.Language='Spa') AS 'Spa'
FROM Items I
INNER JOIN Texts T ON I.ID=T.ItemID
but i get this result:
ID Type Eng Spa
================================
1 0 Hi there! NULL
1 0 NULL Holla!
2 0 Bye! NULL
2 0 NULL bye in Spanish!
I don't see why a join is necessary. You can just use conditional aggregation:
select t.itemid,
max(case when t.language = 'Eng' then t.text end) as Eng,
max(case when t.language = 'Spa' then t.text end) as Spa
from texts t
group by t.itemid;
Use nesting to make two joins on same table with a filter (where clause) .
Below i have tested on MySQL
SELECT
i.id, eng_table.text AS eng, spa_table.text AS spa
FROM
i
LEFT OUTER JOIN
(SELECT
ItemID AS ID, Text
FROM
t
WHERE
Language = 'ENG') AS eng_table ON i.id = eng_table.id
LEFT OUTER JOIN
(SELECT
ItemID AS ID, Text
FROM
t
WHERE
Language = 'SPA') AS spa_table ON i.id = spa_table.id
Regards,
Bikxs
A solution using joins would look something like....
Select i.ID
,i.[Type]
,t1.[Text] AS [Eng]
,t2.[Text] AS [Spa]
FROM Items i
INNER JOIN Texts t1 ON i.ID = t1.ItemID AND t1.[Language] = 'Eng'
INNER JOIN Texts t2 ON i.ID = t2.ItemID AND t2.[Language] = 'Spa'
WITH Eng
AS
(
SELECT * FROM Texts t WHERE t.Language = 'Eng'
),
Spa
AS
(
SELECT * FROM Texts t WHERE t.Language = 'Spa'
)
SELECT i.ID, i.Type, e.Text AS Eng, s.Text AS Spa
FROM Items i
LEFT JOIN Eng e ON i.ID = e.ItemID
LEFT JOIN Spa s ON i.ID = s.ItemID
Even you can use a dynamic sql query.
Query
DECLARE #query VARCHAR(MAX)
SELECT #query = 'SELECT t1.itemid, MAX(t2.[Type]) AS [Type], ' +
STUFF
(
(
SELECT DISTINCT ',MAX(CASE WHEN t1.[language] = '''+ [language]
+ ''' THEN t1.[Text] END) AS ' + [Language]
FROM Texts
FOR XML PATH('')
),
1,1,'');
SELECT #query += ' FROM texts t1 JOIN items t2 ON t1.ItemId = t2.ID GROUP BY t1.itemid;';
EXECUTE(#query);
Because subquery returns more than one value, #parameter cannot be set. If I use SELECT TOP 1 Name it works. How can I sort it out?
DECLARE #parameter nvarchar(50)
SELECT #parameter = (SELECT Name FROM Choices
JOIN Position ON Position.PositionId = Choices.PositionId
WHERE Choices.CvId=1230)
SELECT * FROM Adverts WHERE Name LIKE '%' + #parameter + '%'
why not merged the 2 query into 1 ?
select a.*
from Choices c
inner join Position p on c.PositionId = p.PositionId
inner join Adverts a on p.Name like '%' + a.Name + '%'
where c.CvID = 1230
Attempted Subquery using alias
SELECT
*,
IQ.EndPart,
IQ.QtyToShip
FROM
parts p
INNER JOIN (
select
*,
(case when c.kitno is null then l.partno else c.partno end) as [EndPart],
(case when c.kitno is null then l.TotalQuantity else c.reqqty end) as [QtyToShip]
FROM
shipments s
INNER JOIN shipments_li l ON s.ShipmentNo = l.ShipmentNo
LEFT JOIN ProductConfiguration c ON l.PartNo = c.KitNo WHERE s.Status='N' and year(s.OrderDate)>2007
) IQ ON p.partno = IQ.EndPart
Looking for a way to join the parts table to my query below, using the part # which is aliased as EndPart. If there is another way to acheive the results of taking two columns and combining them instead of case and an alias that would be a great alternative as well. All my searches of other individuals quest to achieve the same have yielded the result you cannot perform a join based on alias because the results have not been determined at that point, recommending a subquery as a workaround. I'm just not sure how to acheive working results. The above query was what I attempted to get working. Any help appreciated. Thanks in advance.
Original Query
SELECT
*,
(case when c.kitno is null then l.partno else c.partno end) as [EndPart],
(case when c.kitno is null then l.TotalQuantity else c.reqqty end) as [QtyToShip]
FROM
shipments s
INNER JOIN shipments_li l ON s.ShipmentNo = l.ShipmentNo
LEFT JOIN ProductConfiguration c ON l.PartNo = c.KitNo
WHERE
s.Status='N'
and year(s.OrderDate)>2007
order by s.shipmentno
More proper way
--- CREATE TempTable
DECLARE #tblTemp AS TABLE (EndPart INT,
QtyToShip INT)
INSERT INTO #tblTemp (EndPart, QtyToShip)
SELECT
(CASE WHEN c.kitno IS NULL
THEN l.partno ELSE c.partno END) AS [EndPart],
(CASE WHEN c.kitno IS NULL
THEN l.TotalQuantity
ELSE c.reqqty END) AS [QtyToShip]
FROM dbo.Shipments s WITH(NOLOCK)
INNER JOIN shipments_li l WITH(NOLOCK) ON s.ShipmentNo = l.ShipmentNo
LEFT JOIN ProductConfiguration c WITH(NOLOCK) ON l.PartNo = c.KitNo
WHERE s.Status='N' AND YEAR(s.OrderDate)>2007
SELECT
p.*,
tmp.EndPart,
tmp.QtyToShip
FROM dbo.parts p WITH(NOLOCK)
INNER JOIN #tblTemp tmp ON p.partno = tmp.EndPart
I have an SQL query that has an id field - think of it as a foreign key. I need to make a desicion based on the value of this id field such that:
If the value is less then 3100, run a nested fetch from table B.
If the value is greater then 3100, run a nested fetch from a table C.
The statement looks like this:
Select a.ID, a.SN, a.User_Ident,
(select b.first_name from b where b.ident = a.User_Ident) as 'First Name',
(select b.last_name from b where b.ident = a.User_Ident) as 'Last Name',
from a
where ...
What I would like to accomplish is something like this:
Select a.ID, a.SN, a.User_Ident,
when a.User_Ident > 3100 then
(select b.first_name from b where b.ident = a.User_Ident) as 'First Name',
(select b.last_name from b where b.ident = a.User_Ident) as 'Last Name'
else
(select c.name from c where c.ident = a.User_Ident) as 'Name'
from a
where ....
Is this possible?
UPDATE: Your answers suggested I use left joins. My query already contains several left outer joins, so I don't know how this would work. Here is the complete query:
select
A.Ident,
A.Serial_Number,
A.Category_Ident,
C.Description as Category,
A.Purchase_Order,
A.Manufacturer_Ident,
M.Description as Manufacturer,
A.Hardware_Model,
A.Processor_Quantity,
A.Processor_Speed_Hertz,
A.Memory_Installed_Bytes,
A.Memory_Maximum_Bytes,
A.Memory_Slots_Used,
A.Memory_Slots_Total,
A.Storage_Capacity_Bytes,
A.Video_Memory_Bytes,
A.Screen_Size_Diagonal_Inches,
A.Software_Ident,
S.Software_Title,
A.Account_Ident,
T.Description as Account,
A.User_Ident,
(select Q.dbo.P.user_name from Q.dbo.P where Q.dbo.P.ident = A.User_Ident) as 'User Name',
(select Q.dbo.P.first_name from Q.dbo.P where Q.dbo.P.ident = A.User_Ident) as 'First Name',
(select Q.dbo.P.last_name from Q.dbo.P where Q.dbo.P.ident = A.User_Ident) as 'Last Name',
(select Q.dbo.R.description from Q.dbo.R where Q.dbo.R.ident = (select Q.dbo.P.rank from Q.dbo.P where Q.dbo.P.ident = A.User_Ident)) as 'Rank',
(select Q.dbo.P.phone from Q.dbo.P where Q.dbo.P.ident = A.User_Ident) as 'Phone',
(select Q.dbo.P.smtp_address from Q.dbo.P where Q.dbo.P.ident = A.User_Ident) as 'Email',
(select Q.dbo.O.description from Q.dbo.O where Q.dbo.O.ident = (select Q.dbo.P.organization_ident from Q.dbo.P where Q.dbo.P.ident = A.User_Ident)) as 'Organization',
(select Q.dbo.L.description from Q.dbo.L where Q.dbo.L.ident = (select Q.dbo.P.location_ident from Q.dbo.P where Q.dbo.P.ident = A.User_Ident)) as 'Location',
A.Disposition_Ident,
D.Description as Disposition,
A.Notes,
A.Updated,
A.UpdatedBy,
A.Label,
A.Scanned,
S.Licensed
FROM Assets
left outer join C on A.Category_Ident = C.Ident
left outer join M on A.Manufacturer_Ident = M.Ident
left outer join S on A.Software_Ident = S.Ident
left outer join T on A.Account_Ident = T.Ident
left outer join D on A.Disposition_Ident = D.Ident
WHERE ((T.Description like '%' + #Account + '%') or (A.Account_Ident like '%' + #Account + '%'))
order by Serial_Number
Many ways to skin a cat, but I think this approach is worth a try, using a UNION to combine the results of the 2 different conditions (1 query joined to b for ids > 3100, and another query joined to c for ids <= 3100).
You have to return the same fields (you can't as you indicated you wanted), return 1 "name" field when looking at c when you return 2 fields for the b condition. Hence, in this example, when you join to c, it returns "name" as First Name, and returns a blank Last Name value.
Select a.ID, a.SN, a.User_Ident, b.first_name AS 'First Name', b.last_name AS 'Last Name'
FROM a
JOIN b ON a.User_Ident = b.ident
WHERE (a.User_Ident > 3100)
AND (......)
UNION ALL
Select a.ID, a.SN, a.User_Ident, c.name AS 'First Name', '' AS 'Last Name'
FROM a
JOIN c ON a.User_Ident = c.ident
WHERE (a.User_Ident <= 3100)
AND (......)
I'd accomplish this with two left joins and a case statement:
select a.field1,
case when b.lastname is not null then b.firstname else c.firstname end,
case when b.lastname is not null then b.lastname else c.larstname end
from table1 a
left join table2 b
on a.id = b.id
left join table3 c
on a.id = c.id
Note I used lastname is null filed in both case staments, becasue tyou probably don;t want the first name form one table and the last name form the other and lastname is less likely to be null than the firstname in the actual table.
Union would work(beat me there), or you could use an inline function as well. Like the others have said you must return same set of fields.
A slight variation on HLGEM's answer
select a.field1,
case when b.lastname is not null then b.firstname else c.firstname end,
case when b.lastname is not null then b.lastname else c.larstname end
from table1 a
left join table2 b
on a.User_Ident > 3100 AND a.id = b.id
left join table3 c
on a.User_Ident <= 3100 AND a.id = c.id
CASE can only return a column, not a row, and you can't correlate queries into it afaik. And no matter what, a result set must have a static amount of columns.
I think what you would want would be a result set where if the First Name or Last Name was filled out the Name was null.
a.ID | a.SN | Name | First Name | Last Name
1 | # | Name | null | null
2 | # | null | John | Doe
My take on the outer join solution is:
SELECT
a.id
,a.ssn
,a.user_ident
,case when a.user_ident <= 3100 then c.name else b.lastname end LastName
,case when a.user_ident <= 3100 then '' else b.firstname end FirstName
from a
left outer join b
on b.ident = a.user_ident
left outer join c
on c.ident = a.user_ident
A query cannot vary the number of columns returned (at least not in any system I'm familiar with), so if you have a "case C" situation and only have Name, I would return it as LastName and set FirstName to the empty string. This could be made a NULL, if that fits your application better.