I originally had the following query on sql:
SELECT PROJECT_TYPE.PROJECT_TYPE_NAME, PROJECT.PROJECT_NAME, STATUS_TYPE.STATUS_TYPE_NAME,
COUNT(*) AS Tasks
FROM TASK
INNER JOIN PROJECT ON PROJECT.PROJECT_ID = TASK.PROJECT_ID
AND PROJECT.POURCENTAGE < 100 /* the following ANDs filters out inactive projects */
AND PROJECT.PROJECT_TYPE < 6
AND PROJECT.PROJECT_STATUS_ID < 3
INNER JOIN PROJECT_TYPE ON PROJECT.PROJECT_TYPE = PROJECT_TYPE.PROJECT_TYPE_ID
INNER JOIN STATUS_TYPE ON TASK.STATUS_TYPE_ID = STATUS_TYPE.STATUS_TYPE_ID
INNER JOIN PRIORITY_TYPE ON TASK.PRIORITY_TYPE_ID = PRIORITY_TYPE.PRIORITY_TYPE_ID
AND NOT PRIORITY_TYPE.PRIORITY_TYPE_NAME = 'Hold'
AND STATUS_TYPE.STATUS_TYPE_NAME IN ('To do','In Progress', 'To Verify') /* only include projects in these 3 statuses */
GROUP BY PROJECT_TYPE.PROJECT_TYPE_NAME, PROJECT.PROJECT_NAME, STATUS_TYPE.STATUS_TYPE_NAME
order by 2, case status_type_name /* orders by status */
when 'To do' then 1
when 'In Progress' then 2
when 'To Verify' then 3
else 4
end
which correctly displayed the count of tasks in a certain status as such. However, I wanted to replace the
project.project_name
table with the shorter description listed in another table called
project.project_desc
, which looks like this. I attempted to implement this by replacing all project.project_name's with project.project_desc, and adding
AND PROJECT.PROJECT_DESC IS NOT NULL
under the first inner join. However, this results in the following error
SQL Error (306): The text, ntext, and image data types cannot be
compared or sorted, except when using IS NULL or LIKE operator.
I'm not sure what's wrong with this now, all of the null values should be filtered out so i'm confused on why the query doesn't run the same way as it did before, just reading a different table instead. I do not have access to edit the database, so these changes must be implemented through the query.
FWIW, I find this easier to read...
SELECT pt.project_type_name
, p.project_name
, st.status_type_name
, COUNT(*) tasks
FROM task t
JOIN project p
ON p.project_id = t.project_id
JOIN project_type pt
ON pt.project_type_id = p.project_type
JOIN status_type st
ON st.status_type_id = t.status_type_id
JOIN priority_type xt
ON xt.priority_type_id = task.priority_type_id
WHERE p.pourcentage < 100
AND p.project_type < 6
AND p.project_status_id < 3
AND xt.priority_type_name != 'hold'
AND st.status_type_name IN('to do','in progress', 'to verify')
GROUP
BY pt.project_type_name
, p.project_name
, st.status_type_name
ORDER
BY p.project_name
, FIELD(status_type_name,'to do','in progress','to verify')
Related
I think my attempt of wording this is going to be more difficult than sharing the code; However...
Firstly, I'm using SQL Server and extracting information from SAP B1.
I'm trying to generate a CSV file from my SQL Dataset to import into a logistics solution.
OrderNo
NumberOfItems
ItemNumber
12345
2
1
12345
2
2
45678
3
1
45678
3
2
45678
3
3
Using the above table, Order number 12345 would be a TOP 2 function, Order number 45678 would be a TOP 3 function.
The #TOPNUMBER will be pulled from an invoice within SAP so it will be dynamic for each Order number.
When I've writte my query I have performed an inner join using <> to bring through thousands of individual results, then filtering down using the TOP function. (which may have been my first mistake)
DECLARE #NUM AS INT = 3
SELECT TOP (#NUM) --Top Function to be replaced with "Number Of ITems"
T0.[DocNum] AS 'Order_No',
ISNULL(T0.NumAtCard,'') AS 'Cust_Ord_No',
Convert(varchar,T0.DocDate,103) AS 'Order_Date',
'Delivery' AS 'Order_Type',
T0.CardName as 'Del_Name',
ISNULL(T12.buIldingS,'') AS 'Del_Addr_1',
ISNULL(T12.BlockS,'') AS 'Del_Addr_2',
ISNULL(T12.StreetS,'') AS 'Del_Addr_3',
ISNULL(T12.CityS,'') AS 'Del_Town',
ISNULL(T12.CountyS,'') AS 'Del_County',
ISNULL(T12.ZipCodeS,'') AS 'Postal_code',
ISNULL(T12.CountryS,'') AS 'Ctry_Code',
ISNULL(t5.Tel1,'') AS 'Contact_Tel_1',
ISNULL(T5.Tel2,'') AS 'Contact_Tel_2',
ISNULL(T5.Cellolar,'') AS 'Contat_Tel_Mob',
ISNULL(T5.E_mailL,'') AS 'Contact_Email',
ISNULL(T0.Comments,'') AS 'Order_Notes',
'00:05' AS 'Unload_Time',
'' AS 'Delivery_Method',
convert(varchar,DateAdd(Day,-7,GETDATE()),103) AS 'Required_Date',
ISNULL('10:00','') AS 'Required_Time_F', ---- Field to be created in sap
ISNULL('16:00','') AS 'Required_Time_T', ---- Field to be created in sap
Concat('Item ',Format(T1.DocEntry,'000')) as 'Item_Code',
Concat('Item ',Format(T1.DocEntry,'000'),' Of ',FORMAT(#NUM,'000')) as 'Item_Desc',
Concat(T0.DocNum,Format(T1.DocEntry,'000'),FORMAT(#NUM,'000')) AS 'package_id',
'1' AS Item_Qty,
T0.Weight/#NUM AS 'Item_Wgt',
'' AS 'Item_Cube',
convert(varchar,DateAdd(Day,-7,GETDATE()),103) AS 'Item_OnHand_Date'
FROM OINV T0 INNER JOIN INV12 T12 ON T0.DocEntry = T12.DocEntry INNER JOIN OCPR T5 ON T5.[CntctCode] = T0.[CntctCode] INNER JOIN ORDR T1 ON T1.DocNum <> T0.DocEntry
WHERE T0.DocNum > '1647674' AND T0.TrnspCode = 1
ORDER BY T1.DocEntry
This code worked perfectly when I was using WHERE T0.DocNum = '1647674' AND T0.TrnspCode = 1. As soon as I've changed it to a where clause with multiple DocNums it's falling flat on its face.
I'm thinking the easier option may be around me removing the Select Top and the Inner join on ORDR and OINV, and using my #NUM variable (from each document) to only actually give me the required number of lines instead of creating lots and filtering it down?
Any help will be appreciated as it took me a good couple of hours to get this to export in a format in which the CSV file takes with no issues!
---- EDIT ---- Update on the code, i think i've got somewhere close by tweaking a few things, i've actually changed the <> join on the ordr table, to a <= join relating to the variable i'm declaring..
I've ditched the variable number, and replaced it with a dynamic field within SAP.
SELECT
T0.[DocNum] AS 'Order_No',
ISNULL(T0.NumAtCard,'') AS 'Cust_Ord_No',
Convert(varchar,T0.DocDate,103) AS 'Order_Date',
'Delivery' AS 'Order_Type',
T0.CardName as 'Del_Name',
ISNULL(T12.buIldingS,'') AS 'Del_Addr_1',
ISNULL(T12.BlockS,'') AS 'Del_Addr_2',
ISNULL(T12.StreetS,'') AS 'Del_Addr_3',
ISNULL(T12.CityS,'') AS 'Del_Town',
ISNULL(T12.CountyS,'') AS 'Del_County',
ISNULL(T12.ZipCodeS,'') AS 'Postal_code',
ISNULL(T12.CountryS,'') AS 'Ctry_Code',
ISNULL(t5.Tel1,'') AS 'Contact_Tel_1',
ISNULL(T5.Tel2,'') AS 'Contact_Tel_2',
ISNULL(T5.Cellolar,'') AS 'Contat_Tel_Mob',
ISNULL(T5.E_mailL,'') AS 'Contact_Email',
ISNULL(T0.Comments,'') AS 'Order_Notes',
'00:05' AS 'Unload_Time',
'' AS 'Delivery_Method',
convert(varchar,DateAdd(Day,-7,GETDATE()),103) AS 'Required_Date',
ISNULL('10:00','') AS 'Required_Time_F', ---- Field to be created in sap
ISNULL('16:00','') AS 'Required_Time_T', ---- Field to be created in sap
Concat('Item ',Format(T1.DocEntry,'000')) as 'Item_Code',
Concat('Item ',Format(T1.DocEntry,'000'),' Of ',FORMAT(T0.U_PACKQTY,'000')) as 'Item_Desc',
Concat(T0.DocNum,Format(T1.DocEntry,'000'),FORMAT(T0.U_PACKQTY,'000')) AS 'package_id',
'1' AS Item_Qty,
T0.Weight/T0.U_PACKQTY AS 'Item_Wgt',
'' AS 'Item_Cube',
convert(varchar,DateAdd(Day,-7,GETDATE()),103) AS 'Item_OnHand_Date'--,
FROM OINV T0 INNER JOIN INV12 T12 ON T0.DocEntry = T12.DocEntry INNER JOIN OCPR T5 ON T5.[CntctCode] = T0.[CntctCode] INNER JOIN ORDR T1 ON T1.DocEntry <= T0.U_PACKQTY
WHERE T0.DocNum IN ('1647775','1647777','1647778')
The WHERE T0.DocNum IN will be replaced with another where clause to look for "Van Delivery" transport types, and DocNum which will be greater than previously exported DocNum, this will probably be by inserting the "MAX" DocNum into a table at the time i export it, and then using this "MAX" Docnum as a "Min" value in my where clause, so this should always look for new orders only. (I think!)
I think DocNum is of type varchar
I am filtering the data of more than one table by sql select query and for that I am using left outer join in c#.net. So by excuting this query filter is not working properly.
For ex : I have data whose branchid is 1 and yearid is 1. So when excute the query it works fine i.e. it shows that data only whose branch and year id is 1.
other data whose branchid is 2 and yearid is 1. So when I am excuting the query according to this filter at that time it shows branchid is 1 and yearid is 1 and also branchid is 2 and yearid is 1.
means at second time it shows whole data of branch and yearid. So at that time filter is not working.
Here is my query
SELECT DISTINCT
Client.clientname AS ClientName ,
RetailInvoice.invoiceno AS InvoiceNo ,
RetailInvoice.pono AS PoNO ,
RetailInvoice.issuedate AS IssueDate ,
RetailInvoice.duedate AS DueDate ,
RetailInvoice.discount AS Discount ,
RetailInvoice.shipping AS Shipping ,
RetailInvoice.tax AS Tax ,
RetailInvoice.vat AS Vat ,
RetailInvoice.sese AS Sese ,
RetailInvoice.paymenttype AS PaymentType ,
RetailInvoice.chequeno AS Chequeno ,
RetailInvoice.totalamt AS TotalAmt ,
RetailInvoice.description AS Description ,
RetailInvoice.paymentpaid AS PaymentPaid ,
RetailInvoice.subtotal AS Subtotal ,
RetailInvoicePayment.productid AS ProductName ,
RetailInvoicePayment.uom AS Uom ,
RetailInvoicePayment.quantity AS Quantity ,
RetailInvoicePayment.price AS Price
FROM tbl_retailinvoice RetailInvoice
LEFT OUTER JOIN tbl_retailinvoicepayment RetailInvoicePayment
ON RetailInvoice.invoiceno = RetailInvoicePayment.invoiceno
LEFT OUTER JOIN tbl_clientdetail Client
ON RetailInvoice.clientid = Client.clientid
WHERE RetailInvoice.BranchID = 1
AND RetailInvoice.YearID = 1
AND RetailInvoice.invoiceno = 1;
In your query:
FROM tbl_retailinvoice RetailInvoice
LEFT OUTER JOIN tbl_retailinvoicepayment RetailInvoicePayment
ON RetailInvoice.invoiceno = RetailInvoicePayment.invoiceno
LEFT OUTER JOIN tbl_clientdetail Client
ON RetailInvoice.clientid = Client.clientid
WHERE RetailInvoice.BranchID = 1
AND RetailInvoice.YearID = 1
AND RetailInvoice.invoiceno = 1;
All three conditions in the WHERE clause are focused on the table RetailInvoice. You say that even if you change the where condition to this:
WHERE RetailInvoice.BranchID = 2
AND RetailInvoice.YearID = 1
AND RetailInvoice.invoiceno = 1;
..that it still shows you rows where RetailInvoice.BranchID = 1. Vaguely speaking, that shouldn't be possible, since your WHERE clause would specifically dictate that only rows with a BranchID of 2 be returned. I say "vaguely speaking" because I don't have a lot of information to go on here, but in principle what you're saying seems nonsensical.
Something in the description of the problem doesn't add up to me. This problem should not be related to the LEFT JOIN, since none of the WHERE conditions point to one of the tables included by LEFT JOIN. In other words, the problem appears to be elsewhere.
FYI, LEFT JOIN simply means "Show me the information from
RetalInvoice even if there are no matching rows in the
RetailInvoicePayment or Client tables."
As opposed to an INNER JOIN, which would only show you data where a matching row was present in all three tables.
I'm wondering if there is a way to have a complete select statement and if no row is returned to return a row with a default value in a specific field (SQL Server)? Here's a generic version of my SQL to better explain:
SELECT COUNT(CASE WHEN CAST(c.InjuryDate as DATE)>DATEADD(dd,-60, getdate ()) THEN b.InjuryID end) InjuryCount, a.PersonID
FROM Person_Info a
JOIN Injury_Subject b on b.PersonID=a.PersonID
JOIN Injury_Info c on c.InjuryID=b.InjuryID
WHERE EXISTS (SELECT * FROM Hospital_Record d WHERE d.PersonID=b.PersonID and d.InjuryID=b.InjuryID) --There could be multiple people associated with the same InjuryID
GROUP BY a.PersonID
If NOT EXISTS (SELECT * FROM Hospital_Record d WHERE d.PersonID=a.PersonID) THEN '0' in InjuryCount
I want a row for each person who has had an injury to display. Then I'd like a count of how many injuries resulted in hospitalizations in the last 60 days. If they were not hospitalized, I'd like the row to still be generated, but display '0' in InjuryCount column. I've played with this a bunch, moving my date from the WHERE to the SELECT, trying IF ELSE combos, etc. Could someone help me figure out how to get what I want please?
It's hard to tell without an example of input and desired output, but I think this is what you are going for:
select
InjuryCount = count(case
when cast(ii.InjuryDate as date) > dateadd(day,-60,getdate())
then i.InjuryId
else null
end
)
, p.PersonId
from Person_Info p
left join Hosptal_Record h on p.PersonId = h.PersonId
left join Injury_Subject i on i.PersonId = h.PersonId
and h.InjuryId = i.InjuryId
left join Injury_Info ii on ii.InjuryId = i.InjuryId
group by p.PersonId;
I have a complex query to retrieve some results:
EDITED QUERY (added the UNION ALL):
SELECT t.*
FROM (
SELECT
dbo.Intervencao.INT_Processo, analista,
ETS.ETS_Sigla, ATC.ATC_Sigla, PAT.PAT_Sigla, dbo.Assunto.SNT_Peso,
CASE
WHEN ETS.ETS_Sigla = 'PE' AND (PAT.PAT_Sigla = 'LIB' OR PAT.PAT_Sigla = 'LBR') THEN (0.3*SNT_Peso)
WHEN ETS.ETS_Sigla = 'CD' THEN (0.3*SNT_Peso)*0.3
ELSE SNT_Peso
END AS PESOAREA,
CASE
WHEN a.max_TEA_FimTarefa IS NULL THEN a.max_TEA_InicioTarefa
ELSE a.max_TEA_FimTarefa
END AS DATA_INICIO_TERMINO,
ROW_NUMBER() OVER (PARTITION BY ATC.ATC_Sigla, a.SRV_Id ORDER BY TEA_FimTarefa DESC) AS seqnum
FROM dbo.Tarefa AS t
INNER JOIN (
SELECT
MAX(dbo.TarefaEtapaAreaTecnica.TEA_InicioTarefa) AS max_TEA_InicioTarefa,
MAX (dbo.TarefaEtapaAreaTecnica.TEA_FimTarefa) AS max_TEA_FimTarefa,
dbo.Pessoa.PFJ_Descri AS analista, dbo.AreaTecnica.ATC_Id, dbo.Tarefa.SRV_Id
FROM dbo.TarefaEtapaAreaTecnica
LEFT JOIN dbo.Tarefa ON dbo.TarefaEtapaAreaTecnica.TRF_Id = dbo.Tarefa.TRF_Id
LEFT JOIN dbo.AreaTecnica ON dbo.TarefaEtapaAreaTecnica.ATC_Id = dbo.AreaTecnica.ATC_Id
LEFT JOIN dbo.ServicoAreaTecnica ON dbo.TarefaEtapaAreaTecnica.ATC_Id = dbo.ServicoAreaTecnica.ATC_Id
AND dbo.Tarefa.SRV_Id = dbo.ServicoAreaTecnica.SRV_Id
INNER JOIN dbo.Pessoa ON dbo.Pessoa.PFJ_Id = dbo.ServicoAreaTecnica.PFJ_Id_Analista
GROUP BY dbo.AreaTecnica.ATC_Id, dbo.Tarefa.SRV_Id, dbo.Pessoa.PFJ_Descri
) AS a ON t.SRV_Id = a.SRV_Id
INNER JOIN dbo.TarefaEtapaAreaTecnica AS TarefaEtapaAreaTecnica_1 ON
t.TRF_Id = TarefaEtapaAreaTecnica_1.TRF_Id
AND a.ATC_Id = TarefaEtapaAreaTecnica_1.ATC_Id
AND a.max_TEA_InicioTarefa = TarefaEtapaAreaTecnica_1.TEA_InicioTarefa
LEFT JOIN AreaTecnica ATC ON TarefaEtapaAreaTecnica_1.ATC_Id = ATC.ATC_Id
LEFT JOIN Etapa ETS ON TarefaEtapaAreaTecnica_1.ETS_Id = ETS.ETS_Id
LEFT JOIN ParecerTipo PAT ON TarefaEtapaAreaTecnica_1.PAT_Id = PAT.PAT_Id
LEFT OUTER JOIN dbo.Servico ON a.SRV_Id = dbo.Servico.SRV_Id
INNER JOIN dbo.Intervencao ON dbo.Servico.INT_Id = dbo.Intervencao.INT_Id
LEFT JOIN dbo.Assunto ON dbo.Servico.SNT_Id = dbo.Assunto.SNT_Id
) t
The result is following:
It works good, the problem is that I was asked that if when a row is not present on this query, it must contain values from another table (ServicoAreaTecnica), so I got this query for the other table based on crucial information of the first query. So if I UNION ALL I get this:
Query1 +
UNION ALL
SELECT INN.INT_Processo,
PES.PFJ_Descri,
NULL, --ETS.ETS_Sigla,
ART.ATC_Sigla,
NULL ,--PAT.PAT_Sigla,
ASS.SNT_Peso,
NULL, --PESOAREA
NULL, --DATA_INICIO_TERMINO
NULL --seqnum
FROM dbo.ServicoAreaTecnica AS SAT
INNER JOIN dbo.AreaTecnica AS ART ON ART.ATC_Id = SAT.ATC_Id
INNER JOIN dbo.Servico AS SER ON SER.SRV_Id = SAT.SRV_Id
INNER JOIN dbo.Assunto AS ASS ON ASS.SNT_Id = SER.SNT_Id
INNER JOIN dbo.Intervencao AS INN ON INN.INT_Id = SER.INT_Id
INNER JOIN dbo.Pessoa AS PES ON PES.PFJ_Id = SAT.PFJ_Id_Analista
The result is following:
So what I want to do is to remove row number 1 because row number 2 exists on the first query, I think I got it explained better this time. The result should be only row number 1, row number 2 would appear only if query 1 doesn't retrieve a row for that particular INN.INT_Processo.
Thanks!
Ok, there are two ways to reduce your record set. Given that you've already written the code to produce the table with the extra rows, it might be easiest to just add code to reduce that:
Select * from
(Select *
, Row_Number() over
(partition by IntProcesso, Analista order by ISNULL(seqnum, 0) desc) as RN
from MyResults) a
where RN = 1
This will assign row_number 1 to any rows that came from your first query, or to any rows from the second query that do not have matches in the first query, then filter out extra rows.
You could also use outer joins with isnull or coalesce, as others have suggested. Something like this:
Select ISNULL(a.IntProcesso, b.IntProcesso) as IntProcesso
, ISNULL(a.Analista, b.Analista) as Analista
, ISNULL(a.ETSsigla, b.ETSsigla) as ETSsigla
[repeat for the rest of your columns]
from Table1 a
full outer join Table2 b
on a.IntProcesso = b.IntProcesso and a.Analista = b.Analista
Your code is hard to read, because of the lengthy names of everything (and to be honest, the fact that they're in a language I don't speak also makes it a lot harder).
But how about: replacing your INNER JOINs with LEFT JOINs, adding more LEFT JOINs to draw in the alternative tables, and introducing ISNULL clauses for each variable you want in the results?
If you do something like ... Query1 Right Join Query2 On ... that should get only the rows in Query2 that don't appear in Query 1.
Having issues getting a dataset to return with one date per client in the query.
Requirements:
Must have the recent date of transaction per client list for user
Will need have the capability to run through EXEC
Current Query:
SELECT
c.client_uno
, c.client_code
, c.client_name
, c.open_date
into #AttyClnt
from hbm_client c
join hbm_persnl p on c.resp_empl_uno = p.empl_uno
where p.login = #login
and c.status_code = 'C'
select
ba.payr_client_uno as client_uno
, max(ba.tran_date) as tran_date
from blt_bill_amt ba
left outer join #AttyClnt ac on ba.payr_client_uno = ac.client_uno
where ba.tran_type IN ('RA', 'CR')
group by ba.payr_client_uno
Currently, this query will produce at least 1 row per client with a date, the problem is that there are some clients that will have between 2 and 10 dates associated with them bloating the return table to about 30,000 row instead of an idealistic 246 rows or less.
When i try doing max(tran_uno) to get the most recent transaction number, i get the same result, some have 1 value and others have multiple values.
The bigger picture has 4 other queries being performed doing other parts, i have only included the parts that pertain to the question.
Edit (2011-10-14 # 1:45PM):
select
ba.payr_client_uno as client_uno
, max(ba.row_uno) as row_uno
into #Bills
from blt_bill_amt ba
inner join hbm_matter m on ba.matter_uno = m.matter_uno
inner join hbm_client c on m.client_uno = c.client_uno
inner join hbm_persnl p on c.resp_empl_uno = p.empl_uno
where p.login = #login
and c.status_code = 'C'
and ba.tran_type in ('CR', 'RA')
group by ba.payr_client_uno
order by ba.payr_client_uno
--Obtain list of Transaction Date and Amount for the Transaction
select
b.client_uno
, ba.tran_date
, ba.tc_total_amt
from blt_bill_amt ba
inner join #Bills b on ba.row_uno = b.row_uno
Not quite sure what was going on but seems the Temp Tables were not acting right at all. Ideally i would have 246 rows of data, but with the previous query syntax it would produce from 400-5000 rows of data, obviously duplications on data.
I think you can use ranking to achieve what you want:
WITH ranked AS (
SELECT
client_uno = ba.payr_client_uno,
ba.tran_date,
be.tc_total_amt,
rnk = ROW_NUMBER() OVER (
PARTITION BY ba.payr_client_uno
ORDER BY ba.tran_uno DESC
)
FROM blt_bill_amt ba
INNER JOIN hbm_matter m ON ba.matter_uno = m.matter_uno
INNER JOIN hbm_client c ON m.client_uno = c.client_uno
INNER JOIN hbm_persnl p ON c.resp_empl_uno = p.empl_uno
WHERE p.login = #login
AND c.status_code = 'C'
AND ba.tran_type IN ('CR', 'RA')
)
SELECT
client_uno,
tran_date,
tc_total_amt
FROM ranked
WHERE rnk = 1
ORDER BY client_uno
Useful reading:
Ranking Functions (Transact-SQL)
ROW_NUMBER (Transact-SQL)
WITH common_table_expression (Transact-SQL)
Using Common Table Expressions