I have data in two tables and I need in one query get all data and join getting data.
SELECT
kpip.PersonalName,
kpiT.Name,
kpiPR.KpiTarget,
kpiPR.KpiResultDate,
kpiPR.KpiResult
FROM KpiPersonalResult AS kpiPR join KpiPersonal as kpip
on kpiPR.KpiPersonal = kpip.Id join KpiType AS kpiT
on kpip.KpiType = kpiT.Id join MerchantAdministrators as merA
on kpiPR.KpiAdded = merA.Id and kpiPR.KpiResultDate between '2021-04-07' and '2021-04-08'
select
kpiP.PersonalName,
kpiT.Name,
kpiP.KpiTarget
from KpiPersonal as kpiP join KpiType as kpiT
on kpiP.KpiType = kpiT.Id
Based on the fast that the second query has 3 columns of the same name as the first query, I guess you mean to union them:
SELECT
kpip.PersonalName,
kpiT.Name,
kpiPR.KpiTarget,
kpiPR.KpiResultDate,
kpiPR.KpiResult
FROM
KpiPersonalResult AS kpiPR
join KpiPersonal as kpip on kpiPR.KpiPersonal = kpip.Id
join KpiType AS kpiT on kpip.KpiType = kpiT.Id
join MerchantAdministrators as merA on kpiPR.KpiAdded = merA.Id and kpiPR.KpiResultDate between '2021-04-07' and '2021-04-08'
UNION ALL
select
kpiP.PersonalName,
kpiT.Name,
kpiP.KpiTarget,
null, --put suitable default values for the other columns here
null
from
KpiPersonal as kpiP
join KpiType as kpiT on kpiP.KpiType = kpiT.Id
Unioned queries need the same number of columns. I've inserted NULL as default value for the two missing columns in the second query (relative to the first)
UNION makes a resultset grow taller. If you intended for it to grow wider, that is done via JOIN. A simple pattern for doing so is:
WITH query1 AS(
--query 1 here
), query2 AS (
--query2 here
)
SELECT * FROM query1 JOIN query2 ON ...
Side note on formatting and indenting - most people find SQL most readable when all operations that are related are at the same indent level e.g in a typical query, the SELECT FROM WHERE GROUP ORDER keywords are all at the same indent level, with the blocks that relate to them (the list of selected columns, or list of joined tables, list of where'd predicates etc) indented a level again. We also typically don't use as when aliasing tables but we do use it when aliasing columns in the SELECT
Related
I have put down below a query to retrieve from four tables which are
Sales_Invoice, New_Customer, Company_Information, Expense
Query:
select
isnull(sum(Expense.Expense_Amount), 0.00), as ExpenseAmount,
Company_Information.Company_Name,
Sales_Invoice.Invoice_No, Sales_Invoice.Invoice_Date, Sales_Invoice.Item_Name,
New_Customer.Customer_Name, New_Customer.Customer_ID
from
Sales_invoice, Company_Information, New_Customer, Expense
where
Sales_Invoice.Customer_Id = New_Customer.Customer_ID
and Sales_Invoice.Invoice_No = Expense.Invoice_No
group by
Company_Information.Company_Name,
Sales_Invoice.Invoice_No, Sales_Invoice.Invoice_Date, Sales_Invoice.Customer_ID,
Sales_Invoice.Item_Name, New_Customer.Customer_Name, New_Customer.Customer_ID
The query is working well but if the Expense table has no values Expense.Invoice_No does not match with Sales_Invoice.Invoice_No, then the query above will return empty rows.
But what I wish to do is that, if Expense.Invoice_No does not exists then I still want to have my rows provided that expense amount return 0.00
Use standard joins! Then, you can easily handle "missing" relations with a left join.
Your question suggests:
select
coalesce(sum(e.expense_amount), 0.00) as expenseamount,
ci.company_name,
si.invoice_no, si.invoice_date, si.item_name,
nc.customer_name, nc.customer_id
from new_customer nc
inner join company_information ci on ???
inner join sales_invoice si on si.customer_id = nc.customer_id
left join expense e on e.invoice_no = si.invoice_no
group by
ci.company_name,
si.invoice_no, si.invoice_date, si.customer_id,
si.item_name, nc.customer_name, nc.customer_id
Note that you original code seems to me missing a join condition between the customers and companies. I represented it as ??? in the query.
You could also express the same logic with a correlated subquery, which would avoid outer aggregation:
select
(
select coalesce(sum(e.expense_amount), 0.00)
from expense e
where e.invoice_no = si.invoice_no
) as expenseamount,
ci.company_name,
si.invoice_no, si.invoice_date, si.item_name,
nc.customer_name, nc.customer_id
from new_customer nc
inner join company_information ci on ???
inner join sales_invoice si on si.customer_id = nc.customer_id
SQL Query taking too much time to execute. Working fine at UAT. I need to compare data of two tables and want to get difference. Below mention is my query.
Select *
from tblBrandDetailUsers tbdu
inner join tblBrands tbs on tbs.BrandId = tbdu.BrandId
left join tblBrandDetails tbd on tbd.CategoryId = tbdu.CategoryId
and tbd.BrandId = tbdu.BrandId
and tbd.CityId = tbdu.CityId
inner join tblCategory tc on tbdu.CategoryId = tc.CategoryId
inner join tblCity tcc on tcc.CityId = tbdu.CityId
where isnull(tbdu.SaleAmount,-1) <> isnull(tbd.SaleAmount,-1)
and isnull(tbdu.CityId,0) = 3
and isnull(tbdu.TopLevelCategoryId,0) = 2;
Need to optimize query.
a number of things you need to check:
number of rows for each table. the more rows you have the slower it gets. Do you have the same size of data with UAT?
SELECT * : avoid the * and only retrieve columns you need.
ISNULL function on left side of the WHERE predicate will scan the index because it is non-sargable. you can check the answer here and rewrite your predicate without any function on the left side of WHERE clause.
You need to provide a detailed information like actual execution plan. I can only give you a generic answer because not much detail was provided.
Remember the UAT is very different in PROD. the hardware you used, the number of rows, etc..
Every advises in comment looks right. The difference between UAT and Prod should be the volume of data.
Your issue should come of lack or inefficient indices.
You should add compound index on
tblBrandDetails.CategoryId,tblBrandDetails.BrandId, tblBrandDetails.CityId
and on
tblBrandDetailUsers.CategoryId,tblBrandDetailUsers.BrandId, tblBrandDetailUsers.CityId
ensure that all unique ids have a btree index (or similar type of index depending on your DB)
You can also add conditional indices to filter quicker the null values:
https://www.brentozar.com/archive/2015/09/filtered-indexes-and-is-not-null/
Rewrite your query like this :
Select *--> AVOID "*" put all the necessary columns
from tblBrandDetailUsers AS tbdu
inner join tblBrands AS tbs on tbs.BrandId = tbdu.BrandId
left join tblBrandDetails AS tbd on tbd.CategoryId = tbdu.CategoryId
and tbd.BrandId = tbdu.BrandId
and tbd.CityId = tbdu.CityId
inner join tblCategory AS tc on tbdu.CategoryId = tc.CategoryId
inner join tblCity AS tcc on tcc.CityId = tbdu.CityId
where tbdu.SaleAmount <> tbd.SaleAmount
and tbdu.CityId = 3
and tbdu.TopLevelCategoryId = 2
UNION ALL
SELECT * --> AVOID "*" put all the necessary columns
from tblBrandDetailUsers AS tbdu
inner join tblBrands AS tbs on tbs.BrandId = tbdu.BrandId
left join tblBrandDetails AS tbd on tbd.CategoryId = tbdu.CategoryId
and tbd.BrandId = tbdu.BrandId
and tbd.CityId = tbdu.CityId
inner join tblCategory AS tc on tbdu.CategoryId = tc.CategoryId
inner join tblCity AS tcc on tcc.CityId = tbdu.CityId
where tbdu.SaleAmount IS NULL
AND tbd.SaleAmount IS NULL
and tbdu.CityId = 3
and tbdu.TopLevelCategoryId = 2;
Modify the SELECT clause to have only the necessary columns and not *
Be sure that you have index that are close to :
For tblBrandDetailUsers TABLE :
index KEY (CityId, TopLevelCategoryId, BrandId, CategoryId) INCLUDE (SaleAmount)
index KEY (CityId, TopLevelCategoryId, CategoryId) INCLUDE (SaleAmount)
For tblBrandDetails TABLE :
index (CityId, BrandId, CategoryId)
And also :
tblCategory (CategoryId)
tblCity (CityId)
tblBrands (BrandId)
When you will rectify the query especially the SELECT clause, we can give you more accurate indexes, because selected columns have a big weight on indexes performances !
as other suggested, try to add index on columns used for joins
I have query like below , I tried to filter out duplicate columns by using Group BY
SELECT contacts.rowid AS ROW_PASS,
duty_rota.rowid AS ROW_PASS_ROTA,
duty_rota.duty_type AS DUTY_TYPE
FROM duty_rota,
duty_types,
contacts
WHERE duty_rota.duty_type = duty_types.duty_type
AND duty_rota.duty_officer = contacts.duty_id
AND sname IS NOT NULL
GROUP BY contacts.rowid,
duty_rota.rowid,
duty_rota.duty_type
ORDER BY duty_date
After playing with the query little bit I came to know we can't filter out distinct using group by while using ROWID. So can somebody please help me to write code (in SQL) with a logic that
if (any row is completely identical with another row of the query o/p)
{
then display only one column
}
I will be using the output as gridview's data source in C#, so if not in SQL - can you help me whether somehow in C# I can achieve to display only identical columns?
If you want to filter duplicate rows, you can use this query:
SELECT Max(duty_rota.rowid) AS ROW_PASS_ROTA,
duty_rota.duty_type AS DUTY_TYPE
FROM duty_rota,
duty_types,
contacts
WHERE duty_rota.duty_type = duty_types.duty_type
AND duty_rota.duty_officer = contacts.duty_id
AND sname IS NOT NULL
GROUP BY duty_rota.duty_type
ORDER BY DUTY_TYPE
Here you go: http://sqlfiddle.com/#!2/2a038/2
Take out the ROWID's. Example: If your table has 3 columns (colA, colB, colC) you could find exact row dups this way...
select a.* from
(
select count(*) dupCnt, colA, colB, colC from myTable
group by colA, colB, colC
) a
where dupCnt > 1
First, the ROWID is a unique field for each row, so using this field you will never have duplicates. The only solution here is to not use it. It's data does not hold anything you would want to display anyway.
Simply put, if you want no duplicates, you need the DISTINCT keyword:
SELECT DISTINCT field1,
field2
FROM table1,
table2
WHERE table1.key1 = table2.key1;
This will select all Field1, Field2 combinations from the two tables. Due to the DISTINCT keyword, each line will only be in the result list once. Duplicates will not be in the result list.
SELECT DISTINCT duty_rota.duty_type AS DUTY_TYPE
FROM duty_rota,
duty_types,
contacts
WHERE duty_rota.duty_type = duty_types.duty_type
AND duty_rota.duty_officer = contacts.duty_id
AND sname IS NOT NULL
ORDER BY duty_date
You will only need to GROUP BY if you need further operations on the result set, like counting the duplicates. If all you need is "no duplicates", the DISTINCT keyword is exactly what you are looking for.
Edit:
In case I misread your question and you want to see only those, that are duplicates, you need to group and you need to filter based on the groups criteria. You can do that using the HAVING clause. It's kind of an additional WHERE of the groups criteria:
SELECT FIELD1, FIELD2, COUNT(*)
FROM TABLE1, TABLE2
WHERE TABLE1.KEY1 = TABLE2.KEY1
GROUPB BY FIELD1, FIELD2
HAVING COUNT(*) > 1
I have two Tables - tblExpenses and tblCategories as follows
tblExpenses
ID (PK),
Place,
DateSpent,
CategoryID (FK)
tblCategory
ID (PK),
Name
I tried various LINQ approaches to get all distinct records from the above two tables but not with much success. I tried using UNION and DISTINCT but it didnt work.
The above two tables are defined in my Model section of my project which in turn will create tables in SQLite. I need to retrieve all the distinct records from both the tables to display values in gridview.
Kindly provide me some inputs to accomplish this task. I did some research to find answer to this question but nothing seemed close to what I wanted. Excuse me if I duplicated this question.
Here is the UNION, DISTINCT approaches I tried:
DISTINCT # ==> Gives me Repetitive values
(from exp in db.Table<tblExpenses >()
from cat in db.Table<tblCategory>()
select new { exp.Id, exp.CategoryId, exp.DateSpent, exp.Expense, exp.Place, cat.Name }).Distinct();
UNION # ==> Got an error while using UNION
I think union already does the distict when you join the two tables you can try somethin like
var query=(from c in db.tblExpenses select c).Concat(from c in
db.tblCategory select c).Distinct().ToList();
You will always get DISTINCT records, since you are selecting the tblExpenses.ID too. (Unless there are multiple categories with the same ID. But that of course would be really, really bad design.)
Remember, when making a JOIN in LINQ, both field names and data types should be the same. Is the field tblExpenses.CategoryID a nullable field?
If so, try this JOIN:
db.Table<tblExpenses>()
.Join(db.Table<tblCategory>(),
exp => new { exp.CategoryId },
cat => new { CategoryId = (int?)cat.ID },
(exp, cat) => new {
exp.Id,
exp.CategoryId,
exp.DateSpent,
exp.Expense,
exp.Place,
cat.Name
})
.Select(j => new {
j.Id,
j.CategoryId,
j.DateSpent,
j.Expense,
j.Place,
j.Name
});
You can try this queries:
A SELECT DISTINCT query like this:
SELECT DISTINCT Name FROM tblCategory INNER JOIN tblExpenses ON tblCategory.categoryID = tblExpenses.categoryID;
limits the results to unique values in the output field. The query results are not updateable.
or
A SELECT DISTINCTROW query like this:
SELECT DISTINCTROW Name FROM tblCategory INNER JOIN tblExpenses ON tblCategory.categoryID = tblExpenses.categoryID;<br/><br/>
looks at the entire underlying tables, not just the output fields, to find unique rows.
reference:http://www.fmsinc.com/microsoftaccess/query/distinct_vs_distinctrow/unique_values_records.asp
I have this hql query, which works perfect:
select m
from Media m
join m.Productlines p
join m.Categories c
join m.Spaces sp
join m.Solutions so
where m.Uid != 0
and p.Uid in (:productlines)
and c.Uid in (13)
and sp.Uid in (52)
and so.Uid in (15,18)
group by m.Uid
But now it needs to be parameterized/made dynamic, not only the parameters, but also the joins (it is possible to select only from Media, without any joins, and so no *.Uid in will be required in this case).
I dont want to mess around with a StringBuilder instance and build the hql query that way, I would rather like to use the Criteria API, but I cant get a
SELECT m.*
....
GROUP BY m.Uid
query to work with Criteria.
If I add a
Projections.GroupProperty("Uid")
to my query, nhibernate selects
SELECT m.Uid
....
GROUP BY m.Uid
which is of course wrong.
After that, I also need to count the unique rows the query returned, as the result is paged.
So, my other query is quite similiar, but I cant find a Criteria equivalent for
SELECT COUNT(DISTINCT m.Uid)
Here is the HQL:
select count(distinct m.Uid)
from Media m
join m.Productlines p
join m.Categories c
join m.Spaces sp
join m.Solutions so
where m.Uid != 0
and p.Uid in (:productlines)
and c.Uid in (13)
and sp.Uid in (52)
and so.Uid in (15,18)
How can this be done with Criteria API?
Please, (N)Hibernate experts - help me with this, I cant find a working solution. Any help is greatly appreciated!
Group columns are implicitly returned as result, but you can add more columns. AFAIK, you can return full entities:
var query = session.CreateCriteria(typeof(Media), "m")
.Add(Projections.GroupProperty("m"))
.Add(Restrictions.NotEq("m.Uid", 0));
// dynamically add filters
if (filterProductLines)
{
query
.CreateCriteria("m.Productlines", "p")
.Add(Restrictions.Eq("p.Uid", productLines));
}
// more dynamic filters of this kind follow here...
IList<Media> results = query.List<Media>();
To count the full number of results you can just build up the same query with different projection:
var query = session.CreateCriteria(typeof(Media), "m")
.SetProjection(Projections.CountDistinct("m.Uid"));
// rest of the query the same way as above
long totalNumberOfResults = query.UniqueResult<long>();
I'm getting unsure about the Projections.GroupProperty("m"), you need to try this. If it doesn't work, you could make it an DetachedQuery that only returns ids:
var subquery = DetachedCriteria.For(typeof(Media), "m")
.Add(Projections.GroupProperty("m.Uid"))
.Add(Restrictions.NotEq("m.Uid", 0));
// add filtering
var query = session.CreateCriteria(typeof(Media), "outer")
.Add(Subqueries.PropertyIn("outer.Uid", subquery));
IList<Media> results = query.List<Media>();
This creates a sql query like this:
select outer.* // all properties of Media to create an instance
from Media outer
where outer.Uid in (
select Uid
from media m
where // filter
)
var count = session.CreateCriteria(typeof(Media))
// Add other criterias...
.SetProjection(Projections.CountDistinct("Id")) // or whatever the id property of Media class is called
.UniqueResult<long>();
As to your GROUP BY question, the query:
SELECT m.*
....
GROUP BY m.Uid
makes no sense because you need to select only columns that appear in the group by clause or aggregate functions. Could you elaborate a little more as to what exactly are you trying to achieve?