I'm running a pretty simple SQL query on my database, and it seems to be returning the same record over and over, creating an infinite loop. Maybe I'm missing something obvious, but I don't see it. Here's the query:
select s.customer as 'Customer',
s.store as 'Store',
s.item as 'Item',
d.dlvry_dt as 'Delivery',
i.item_description as 'Description',
mj.major_class_description as 'Major Description',
s.last_physical_inventory_dt as 'Last Physical Date',
s.qty_physical as 'Physical Qty',
s.avg_unit_cost as 'Unit Cost',
[qty_physical] * [avg_unit_cost] as Value
from database.DELIVERY d,
database.STORE_INVENTORY s,
database.ITEM_MASTER i,
database.MINOR_ITEM_CLASS mi,
database.MAJOR_ITEM_CLASS mj,
database.STORE_INVENTORY_ADJUSTMENT sa
where sa.store = s.store
and s.last_physical_inventory_dt between '6/29/2011' and '7/2/2011'
and s.customer = '20001'
and s.last_physical_inventory_dt is not null
There is one record that falls on 7/1/2011 and it repeats it forever until I cancel the query.
Any help on preventing this?
You're joining all these tables: database.DELIVERY, database.ITEM_MASTER, database.MINOR_ITEM_CLASS, and database.MAJOR_ITEM_CLASS - without specifying how to join them. You need to specify how these tables are joined with the rest.
If each of these tables has ONLY 100 rows, it will give you 100 * 100 * 100 * 100 rows (100 million) minimum rows! (see Cartesian Join)
You haven't joined all your tables. For example, tables MINOR_ITEM_CLASS, database.MAJOR_ITEM_CLASS & database.ITEM_MASTER are missing joins. Missing joins causes the query engine to do a Cartesian join on the tables not explicitly joined. So you don't have an endless loop, you just many duplicate copies of the same record. Eventually your query will stop.
Add the appropriate joins for those tables & let us how it goes. You could also try adding the DISTINCT key word.
Related
I'm working on writing some queries for a very large (and messy) database on behalf of a client. So far, I've just been grabbing the columns I need and making sure that they contain the data I'm looking for. There have been no issues up until I add anything to my "order by" clause. When I add an order by clause to my query, the SQL Server remains stuck on "executing query." Example of code below:
SELECT TOP 100
PEATR.[EffectiveDate] AS 'Effective Date',
CustomerRoot.[CustomerName] AS 'Name',
CustomerAddressRoot.[Street1] AS 'Address 1',
CustomerAddressRoot.[Street2] AS 'Address 2',
CustomerAddressRoot.[City],
CustomerAddressRoot.[State],
CustomerAddressRoot.[Zip],
CustomerAddressRoot.[Country],
CustomerAddressRoot.[AddressDesc] AS 'Description'
FROM PrEmployeeAccrueTierRoot AS PEATR, CustomerRoot, CustomerAddressRoot
ORDER BY CustomerRoot.[CustomerName]
I have also tried creating an inner join on CustomerRoot and CustomerAddressRoot, as the query is returning repeat data, especially in the "Address 1" column. When I ran the code below, I have received the following error message:
The objects "CustomerRoot" and "CustomerRoot" in the FROM clause have the same exposed names. Use correlation names to distinguish them.
Code:
SELECT TOP 100
PEATR.[EffectiveDate] AS 'Effective Date',
CustomerRoot.[CustomerName] AS 'Name',
CustomerAddressRoot.[Street1] AS 'Address 1',
CustomerAddressRoot.[Street2] AS 'Address 2',
CustomerAddressRoot.[City],
CustomerAddressRoot.[State],
CustomerAddressRoot.[Zip],
CustomerAddressRoot.[Country],
CustomerAddressRoot.[AddressDesc] AS 'Description'
FROM PrEmployeeAccrueTierRoot AS PEATR, CustomerRoot, CustomerAddressRoot
INNER JOIN CustomerRoot ON CustomerAddressRoot.CustomerId=CustomerRoot.CustomerId
I did assign aliases to all of the tables previously, though I was still returning the same error message. Any guidance or suggestions would be much appreciated.
You are performing a cartesian join.
FROM PrEmployeeAccrueTierRoot AS PEATR, CustomerRoot, CustomerAddressRoot
...is the same as...
FROM PrEmployeeAccrueTierRoot AS PEATR
inner join CustomerRoot on 1=1
inner join CustomerAddressRoot on 1=1
There is no join logic.
So, if PrEmployeeAccrueTierRoot has 1000 rows and CustomerRoot has 1000 rows and CustomerAddressRoot has 1000 rows, your result will have 1,000,000,000 rows.
Try two things:
Include join logic.
Your query should look something like this:
SELECT TOP 100
PEATR.[EffectiveDate] AS 'Effective Date',
CustomerRoot.[CustomerName] AS 'Name',
CustomerAddressRoot.[Street1] AS 'Address 1',
CustomerAddressRoot.[Street2] AS 'Address 2',
CustomerAddressRoot.[City],
CustomerAddressRoot.[State],
CustomerAddressRoot.[Zip],
CustomerAddressRoot.[Country],
CustomerAddressRoot.[AddressDesc] AS 'Description'
FROM PrEmployeeAccrueTierRoot AS PEATR
inner join CustomerRoot on CustomerRoot.customerrootid = peatr.customerrootid
inner join CustomerAddressRoot on CustomerAddressRoot.customerrootid = CustomerRoot.customerrootid
ORDER BY CustomerRoot.[CustomerName]
Of course, I don't know what columns you should actually join on. Know thy data.
Then you'll have one problem remaining: If your query (without the TOP 100) would return millions of rows, you're asking the database server to perform all of the logic and gather all of the rows, then sort them by CustomerName, then return the first 100 rows. That could still be slow. You'll want to...
Apply filters.
SELECT TOP 100
PEATR.[EffectiveDate] AS 'Effective Date',
CustomerRoot.[CustomerName] AS 'Name',
CustomerAddressRoot.[Street1] AS 'Address 1',
CustomerAddressRoot.[Street2] AS 'Address 2',
CustomerAddressRoot.[City],
CustomerAddressRoot.[State],
CustomerAddressRoot.[Zip],
CustomerAddressRoot.[Country],
CustomerAddressRoot.[AddressDesc] AS 'Description'
FROM PrEmployeeAccrueTierRoot AS PEATR
inner join CustomerRoot on CustomerRoot.customerrootid = peatr.customerrootid
inner join CustomerAddressRoot on CustomerAddressRoot.customerrootid = CustomerRoot.customerrootid
WHERE CustomerAddressRoot.State = 'Alaska'
ORDER BY CustomerRoot.[CustomerName]
..at least during testing, to speed things up.
I am a bit rusty on SQL so any assistance is appreciated. I am also referencing my SQL textbook but I thought I would try this out.
I am developing a lead scoring model starting with engagement scoring. I created a data extension to house the results and used the following query to populate:
SELECT a.[opportunityid],
a.[first name],
a.[last name],
a.[anticipatedentryterm],
a.[funnelstage],
a.[programofinterest],
a.[opportunitystage],
a.[opportunitystatus],
a.[createdon],
a.[ownerfirstname],
a.[ownerlastname],
a.[f or j visa student],
a.[donotbulkemail],
a.[statecode],
Count(DISTINCT c.[subscriberkey]) AS 'Clicks',
Count(DISTINCT b.[subscriberkey]) AS 'Opens',
Count(DISTINCT b.[subscriberkey]) * 1.5 +
Count(DISTINCT c.[subscriberkey]) * 3 AS 'Probability'
FROM [ug_all_time_joined] a
INNER JOIN [open] b
ON a.[opportunityid] = b.[subscriberkey]
INNER JOIN [click] c
ON a.[opportunityid] = c.[subscriberkey]
GROUP BY a.[opportunityid],
a.[first name],
a.[last name],
a.[anticipatedentryterm],
a.[funnelstage],
a.[programofinterest],
a.[opportunitystage],
a.[opportunitystatus],
a.[createdon],
a.[ownerfirstname],
a.[ownerlastname],
a.[f or j visa student],
a.[donotbulkemail],
a.[statecode]
Something is wrong with my COUNT functions, the query populates the same value in both Clicks and Opens and I don't think it's accurate. The result I am aiming for is how many times a subscriber id appears (which would correspond with the individual clicks/opens, each row is a 1 action).
Thank you!
Why is that surprising?
You have two joins that if you take to their logical conclusion imply that
b.[SubscriberKey] = c.[SubscriberKey]
Hence, counting distinct values will be the same.
You have not provide sample data or desired results. I can speculate, though, that you intend LEFT JOINs so you get some values in one table that are not matched in the other.
When you do an inner join, between a and b, your data is filtered when you join a and c, which will give you incorrect results. having no view of your data and no background of your tables, this is the best guess i have
I have a table called factprojection which has the columns as shown in the image.
I want to multiply the 'value' column which have 'Total Lines & RSV Required'in the 'Measures' column with the 'value' column which have 'Line Average' in the 'Measures' column joining it by crew type. Should I create a temp table and then perform the multiplication? Could anyone help me with this?
N.B. I'm assuming all CrewType and DateKey values are in both tables, so all answers below use inner joins (any rows not matching on both sides are not returned)
Common Table Expressions (CTEs)
You can define Common Table Expressions that perform queries on the table, and then name those queries. You can then join these 'sub-tables', rather than generating any temporary data:
WITH LineAverage as (
select *
from factprojection
where Measure = 'Line Average'
)
,TotalLines as (
select *
from factprojection
where Measure = 'Total Lines & RSV Required'
)
select
LA.CrewType
,LA.DateKey
,LA.Value*TL.Value as newvalue
from LineAverage LA
inner join
TotalLines TL
ON LA.DateKey = TL.DateKey
and LA.CrewType = TL.CrewType
Self join
An equivalent but less visually obvious approach is a self-join, giving the tables different aliases:
select
LA.CrewType
,LA.DateKey
,LA.Value*TL.Value as newvalue
from factprojection LA,
factprojection TL
where LA.DateKey = TL.DateKey
and LA.CrewType = TL.CrewType
and LA.Measure = 'Line Average'
and TL.Measure = 'Total Lines & RSV Required'
Notice the use of restrictions on the Measure values alongside the join conditions in the WHERE clause. Although this query is marginally shorter to write it loses some readability over the CTE approach.
Here I've also used the comma form of an INNER JOIN, where the ON clause is replaced by placing the join conditions in the WHERE clause.
I'm having a problem that I assume is related to the Join in my SQL statement.
select s.customer as 'Customer',
s.store as 'Store',
s.item as 'Item',
d.dlvry_dt as 'Delivery',
i.item_description as 'Description',
mj.major_class_description as 'Major Description',
s.last_physical_inventory_dt as 'Last Physical Date',
s.qty_physical as 'Physical Qty',
s.avg_unit_cost as 'Unit Cost',
[qty_physical]*[avg_unit_cost] as Value
from argus.DELIVERY d
join argus.STORE_INVENTORY s
ON (s.store = d.store)
join argus.ITEM_MASTER i
ON (s.item = i.item)
join argus.MINOR_ITEM_CLASS mi
ON (i.minor_item_class = mi.minor_item_class)
join argus.MAJOR_ITEM_CLASS mj
ON (mi.major_item_class = mj.major_item_class)
where s.last_physical_inventory_dt between '6/29/2011' and '7/2/2012'
and s.customer = '20001'
and s.last_physical_inventory_dt IS NOT NULL
It comes back with a seemingly infinite amount of copies of one record. Is there something wrong with the way I'm joining these tables?
join argus.MINOR_ITEM_CLASS mi
ON (i.minor_item_class = mi.minor_item_class)
join argus.MAJOR_ITEM_CLASS mj
ON (mi.major_item_class = mj.major_item_class)
My guess is that your error resides in one of these 2 joins. When you only use the word JOIN it assumes that you are trying to do an INNER JOIN which returns all records that have at least 1 to 1. I don't know what your data looks like but I am assuming that there is a many to many relationship between minor item class and major item class so when you run this query you are receiving duplicated records for almost every field, but the major item class differs.
I would look at the results. Most of the columns will have repeating data that doesn't change while one of the columns will have a different value for every row. That should tell you that the column with differing data for each row is the column that you should be joining differently.
Otherwise, I would say that your query is formatted correctly.
I normally work with MySQL so not sure how to get a query to work on SQL.
I have 3 tables:
Table1
ODBC_ORDER_LINE_ALL
This contains ORDER_LINE_NETT_TOTAL and also the ORDER_LINE_ORDER_ID
Table 2
ODBC_ORDER_ALL
This contains the ORDER_ID and also the ORDER_ACCOUNT_ID
Table 3
ODBC_ACCOUNT
This contains the ACCOUNT_ACCID and some other information on the account we may need in the future, hence why we are adding it.
I am joining table 1,2,3 together using the above constraints.
What I want to be able to do is generate a Sales Report of Spend showing Account Number and Total Spend but I can't seem to get the syntax correct.
Any help much appreciated.
Here are the tables:
ODBC_ORDER_LINE_ALL
ORDER_LINE_ID
ORDER_LINE_ORDER_ID
ORDER_LINE_DATE
ORDER_LINE_MEDIACODE
ORDER_LINE_SOURCE
ORDER_LINE_PRODUCT_ID
ORDER_LINE_PRODUCT_CODE
ORDER_LINE_PRODUCT_NAME
ORDER_LINE_QUANTITY
ORDER_LINE_NETT_PRICE
ORDER_LINE_VAT_CODE
ORDER_LINE_VAT_RATE
ORDER_LINE_VAT
ORDER_LINE_NETT_TOTAL
ORDER_LINE_VAT_TOTAL
ORDER_LINE_GROSS_TOTAL
ORDER_LINE_UNIT_COST
ORDER_LINE_COST_CURRENCY
ORDER_LINE_COST_EXCHANGE_RATE
ORDER_LINE_TYPE
ORDER_LINE_STAGE
ORDER_LINE_STAGE_DATE
ORDER_LINE_INVOICE_ID
ORDER_LINE_INVOICE_DATE
ORDER_LINE_KIT_COMPONENT
ORDER_LINE_KIT_LINE_ID
ORDER_LINE_USER
ODBC_ORDER_ALL
ORDER_ID
ORDER_TYPE
ORDER_MEDIA_CODE_ID
ORDER_MEDIA_CODE
ORDER_MEDIA_SUBCODE
ORDER_TAKEN_BY
ORDER_DATE
ORDER_ACCOUNT_ID
ORDER_DELIVERY_ACCOUNT_ID
ORDER_SOURCE_ID
ORDER_SOURCE
ORDER_WEB_ORDER_ID
ORDER_MULTI_CLIENT_ID
ORDER_MULTI_CLIENT
ODBC_ACCOUNT
ACCOUNT_ACCID
ACCOUNT_ACC_TYPE
ACCOUNT_REF
ACCOUNT_TITLE
ACCOUNT_FORENAME
ACCOUNT_SURNAME
ACCOUNT_COMPANY_NAME
ACCOUNT_HOUSE_NAME
ACCOUNT_ADD1
ACCOUNT_ADD2
ACCOUNT_ADD3
ACCOUNT_ADD4
ACCOUNT_POSTCODE
ACCOUNT_COUNTRY
ACCOUNT_PHONE1
ACCOUNT_PHONE2
ACCOUNT_FAX1
ACCOUNT_FAX2
ACCOUNT_EMAIL
ACCOUNT_WEBSITE
ACCOUNT_PRICELIST_ID
ACCOUNT_MEDIACAMPAIGN_ID
ACCOUNT_CREATED_DATE
Assuming that the table names are 'Table 1' ODBC_Order_Line_All, 'Table 2' ODBC_Order_All, 'Table 3' ODBC_Account, then you simply need to join the three tables on the relevant joining columns, and sum the order line nett total entries for each account:
SELECT A.Account_AccID, SUM(L.Order_Line_Nett_Total) AS TotalSpend
FROM ODBC_Account AS A
JOIN ODBC_Order_All AS O ON A.Account_Acc_ID = O.Order_Account_ID
JOIN ODBC_Order_Line_All AS L ON O.Order_ID = L.Order_Line_Order_ID
GROUP BY A.Account_AccID;
However, while there is nothing but the Account_AccID selected from ODBC_Account, there is no actual need to select from the ODBC_Account table; you can join just the two tables, yielding a simpler query:
SELECT O.Order_Account_ID AS Acount_AccID, SUM(L.Order_Line_Nett_Total) AS TotalSpend
FROM ODBC_Order_All AS O ON A.Account_Acc_ID = O.Order_Account_ID
JOIN ODBC_Order_Line_All AS L ON O.Order_ID = L.Order_Line_Order_ID
GROUP BY Account_AccID;
There is nothing here that is different in MySQL from any other SQL DBMS, so your knowledge of MySQL should transfer directly.