How can I make this query in SQL Server Compact Edition? - sql

this subquery works in SQL Server:
select systemUsers.name,
(select count(id)
from userIncidences
where idUser = systemUsers.id )
from systemUsers
How can It be made in SQL Compact?
Thanks!

There are cases when you can't avoid a subquery, for instance if you have to include calculated columns that use data from the current and the previous row. Consider this query, for instance:
SELECT
(Current.Mileage - Last.Mileage)/Quantity as MPG
FROM
GasPurchases AS Current
LEFT OUTER JOIN GasPurchases AS Last
ON Last.Date =
(SELECT MAX(PurchaseDate)
FROM GasPurchases
WHERE PurchaseDate < Current.PurchaseDate)
It will cause a parsing error:
SQL Execution Error.
Error Source: SQL Server Compact ADO.NET Data Provider
Error Message: There was an error parsing the query.
I found this thread on MSDN that has a workaround. By changing the subquery so that it returns a set instead of a scalar value, I was able to save and run the following query.
SELECT
(Current.Mileage - Last.Mileage)/Quantity as MPG
FROM
GasPurchases AS Current
LEFT OUTER JOIN GasPurchases AS Last
ON Last.Date IN
(SELECT MAX(PurchaseDate)
FROM GasPurchases
WHERE PurchaseDate < Current.PurchaseDate)

Try this:
SELECT su.Name, COUNT(ui.ID)
FROM systemUsers su
LEFT JOIN userIncidences ui ON ui.idUser = su.ID
GROUP BY su.Name
[Edit:]
I originally had an INNER JOIN just like Tomalak, but I realized that this would exclude users with no incidents, rather than show them with a 0 count. That might even be what you want, but it doesn't match your original.

Thanks guys, DoctaJonez, I found your little post the most helpful with my subquery. Your syntax seems to work with SQL Server Compact v3.5. Here is the query I tried (which works).
By the way, the hardcoded value you see (38046), I know at the time of running the query
insert into tLink (start,stop,associativeobject,linktype,id,name,guid,createTime,modifyTime,externalID,description,linkLabel,LinkDetails)
select newtable.id,stop,associativeobject,linktype,newtable.id,name,guid,createTime,modifyTime,externalID,description,linkLabel,LinkDetails from tLink l, (select id, '38046' as newid from tObject Where name = 'Step 1' and id <> '38046') as newtable
where l.start = newtable.newid and start in (38046)

Something like this? (using Northwind.Order Details]
The Code Snippet:
SELECT [Unit Price] * Quantity AS Cost,
[Unit Price] * Quantity * 1.25 AS CostWithVAT
FROM [Order Details]
Source Airline Reservation System Project

Related

How to order a recordest returned from a query by a field created within that same query (MS ACCESS)

The Query (For this question I do not think that you need to see schema):
SELECT Agencies.AgencyName, (SELECT DISTINCT MAX(Invoices.CostsTotal) FROM Invoices WHERE Contracts.ContractID = Invoices.ContractID) AS MaxInvoice
FROM Contracts
LEFT JOIN Agencies ON Contracts.AgencyID = Agencies.AgencyID
ORDER BY MaxInvoice DESC;
How do we order the recordset returned from a query by a field created within that same query?
I have seen the function FIELDS(INDEX) ? But this does not exist in access? Also not sure that it would even work. In this instance I want to sort the recordset by the MaxInvoice field.
MS Access prompts me to enter a parameter value for MaxInvoice when I attempt to run this query
You can write parent SELECT which wraps your current SELECT.
Like this:
SELECT * FROM (
SELECT Agencies.AgencyName,
(SELECT DISTINCT MAX(Invoices.CostsTotal) FROM Invoices
WHERE Contracts.ContractID = Invoices.ContractID) AS MaxInvoice
FROM Contracts LEFT JOIN Agencies
ON Contracts.AgencyID = Agencies.AgencyID
) AS ContractsLargestInvoice
ORDER BY ContractsLargestInvoice.MaxInvoice DESC;
Most SQL dialects support the use of aliases in the ORDER BY. But MS Access is further from SQL standards than most databases.
I would suggest you rewrite the query to move Invoices into the FROM clause -- using aggregation to get what you want:
SELECT a.AgencyName, MAX(i.CostsTotal) AS MaxInvoice
FROM (Contracts as c LEFT JOIN
Agencies as a
ON c.AgencyID = a.AgencyID) LEFT JOIN
Invoices as i
ON i.ContractID = c.ContractID
GROUP BY a.AgencyName
ORDER BY MAX(i.CostsTotal) DESC;
It seems strange that you are using a LEFT JOIN and choosing a field from the second table and not the first. This could be NULL.

SQL Lookup in MS Access Query

I have an Access Database with a table [Inventory] with following fields:
[Inventory].[Warehouse]
[Inventory].[PartNumber]
I also have a query [TransactionsQry] with following fielfd:
[TransactionsQry].[PartNumber]
[TransactionsQry].[SumofTransactions]
Now I would like to make a new query which shows all part numbers per Warehouse (from table [Inventory]) and look up related (number of) transactions in query [TransactionsQry]. Not every part number in [Inventory] has transactions yet and if so I would like to display "0".
At first I successfully tried this with a DLookup, but the result is a very slow query for very little data.
That is why I tried the following (but unsuccessfully displaying only matched part numbers and an additional error message):
SELECT
Inventory.Warehouse AS Warehouse,
TransactionsQry.PartNumber AS PartNumber,
TransactionsQry.SumofTransactions AS SumofTransactions
FROM Inventory
INNER JOIN TransactionsQry ON Inventory.PartNumber = TransactionsQry.PartNumber;
Any help with solving this issue in SQL is highly appreciated. Thanks.
You would be needing a LEFT JOIN based on what you need. Along with a Nz to treat Nulls as 0. Here is the corrected CODE
SELECT
Inventory.Warehouse AS Warehouse,
TransactionsQry.PartNumber AS PartNumber,
Nz(TransactionsQry.SumofTransactions, 0) AS SumofTransactions
FROM
Inventory LEFT JOIN TransactionsQry
ON
Inventory.PartNumber = TransactionsQry.PartNumber;
You want to use left join rather than inner join for this. Also, table aliases make queries easier to read and write:
SELECT i.Warehouse AS Warehouse,
tq.PartNumber AS PartNumber,
nz(tq.SumofTransactions, 0) AS SumofTransactions
FROM Inventory as i LEFT JOIN
TransactionsQry as tq
ON i.PartNumber = tq.PartNumber;
However, I'm guessing that you really want a group by:
SELECT i.Warehouse AS Warehouse,
tq.PartNumber AS PartNumber,
nz(sum(tq.SumofTransactions), 0) AS SumofTransactions
FROM Inventory as i LEFT JOIN
TransactionsQry as tq
ON i.PartNumber = tq.PartNumber
GROUP BY i.Warehouse, tq.PartNumber;

Error when left joining two databases (SQL Server)

I have a great problem with joining two MSSQL databases together (on the same server) using LEFT JOIN. I run this SQL from the database OLAB_DB and get the error:
The multi-part identifier "OLAP_DB.dbo.OLAP_invoice.UserID" could not be bound.
There seem to be a problem with the DB not being able to find itself, and I have no idea of how to solve this. I have double and triple checked the spelling and rewrote the SQL several times, but now I just have to give up and ask for help :(
This doesn't work:
SELECT TOP 200
COALESCE(LTRIM(RTRIM(contact_db.dbo.ContactTable.EmailAdr)),LTRIM(RTRIM(contact_db.dbo.CustomerTable.EmailAdr))) AS EMAIL,
OLAP_invoice.OrdreLinjeID AS ORDERNO
OLAP_invoice.SalgsPris AS PRICE,
OLAP_invoice.UserID AS CONTACTID
FROM OLAP_invoice,contact_db.dbo.CustomerTable
LEFT JOIN contact_db.dbo.ContactTable
ON OLAP_DB.dbo.OLAP_invoice.UserID = contact_db.dbo.ContactTable.UserID
WHERE contact_db.dbo.CustomerTable.ClientID = OLAP_invoice.ClientID
But skipping the left join and just getting data from the two different databases works just fine.
This works just fine:
SELECT TOP 200
LTRIM(RTRIM(contact_db.dbo.CustomerTable.EmailAdr)) AS EMAIL,
LTRIM(RTRIM(contact_db.dbo.ContactTable.UserID)) AS EMAIL2,
OLAP_invoice.OrdreLinjeID AS ORDERNO
OLAP_invoice.SalgsPris AS PRICE,
OLAP_invoice.UserID AS CONTACTID
FROM OLAP_invoice,contact_db.dbo.CustomerTable
WHERE contact_db.dbo.CustomerTable.ClientID = OLAP_invoice.ClientID
AND contact_db.dbo.ContactTable.UserID = OLAP_invoice.UserID
The reason I need the LEFT JOIN, is because some orders are not registered with a UserID (only ClientID).
I have checked the access rights and there is no problem to access the fields individually, the problem occurs when I have to compare the values in the LEFT JOIN and specifies the absolute path.
Do you have any idea of what can be wrong?
You can try this:
SELECT TOP 200 COALESCE(LTRIM(RTRIM(contact_db.dbo.ContactTable.EmailAdr)),LTRIM(RTRIM(contact_db.dbo.CustomerTable.EmailAdr))) AS EMAIL,
OLAP_invoice.OrdreLinjeID AS ORDERNO
OLAP_invoice.SalgsPris AS PRICE,
OLAP_invoice.UserID AS CONTACTID
FROM OLAP_invoice LEFT JOIN contact_db.dbo.ContactTable ON OLAP_DB.dbo.OLAP_invoice.UserID = contact_db.dbo.ContactTable.UserID, contact_db.dbo.CustomerTable
WHERE contact_db.dbo.CustomerTable.ClientID = OLAP_invoice.ClientID
You are selecting from OLAP_invoice, but joining to OLAP_DB.dbo.OLAP_invoice. You need to qualify the table exactly the same every time, or use an alias.
So either:
FROM OLAP_DB.dbo.OLAP_invoice
left join contact_db.dbo.ContactTable
on OLAP_DB.dbo.OLAP_invoice...
OR
FROM ROM OLAP_invoice
LEFT JOIN ontact_db.dbo.ContactTable
ON OLAP_invoice...
Or you could use an alias as well, less typing that way.
FROM OLAP_invoice OI
LEFT JOIN ontact_db.dbo.ContactTable CT
ON OI...
Personally, I try to avoid having multiple tables in my FROM without intentionally specifying the type of join.
I find something like this to be much more readable and maintainable :
SELECT TOP 200
COALESCE( LTRIM(RTRIM(con.EmailAdr)), LTRIM(RTRIM(cus.EmailAdr)) ) AS EMAIL,
i.OrdreLinjeID AS ORDERNO
i.SalgsPris AS PRICE,
i.UserID AS CONTACTID
FROM OLAP_invoice i
LEFT JOIN contact_db.dbo.CustomerTable cus ON cus.ClientID = i.ClientID
LEFT JOIN contact_db.dbo.ContactTable con ON con.UserID = i.UserID

SQL count - first time

I am learning SQL (bit by bit!) trying to perform a query on our database and adding in a count function to show the total orders that appear against a customers id by counting in a inner join query.
Somehow it is pooling all the data together onto one customer with the count function though.
Can someone please suggest where I am going wrong?
SELECT tbl_customers.*, tbl_stateprov.stprv_Name, tbl_custstate.CustSt_Destination, COUNT(order_id) as total
FROM tbl_stateprov
INNER JOIN (tbl_customers
INNER JOIN (tbl_custstate
INNER JOIN tbl_orders ON tbl_orders.order_CustomerID = tbl_custstate.CustSt_Cust_ID)
ON tbl_customers.cst_ID = tbl_custstate.CustSt_Cust_ID)
ON tbl_stateprov.stprv_ID = tbl_custstate.CustSt_StPrv_ID
WHERE tbl_custstate.CustSt_Destination='BillTo'
AND cst_LastName LIKE '#URL.Alpha#%'
You need a GROUP BY clause in this statement in order to get what you want. You need to figure out what level you want to group it by in order to select which fields to add to the group by clause. If you just wanted to see it on a per customer basis, and the customers table had an id field, it would look like this (at the very end of your sql):
GROUP BY tbl_customers.id
Now you can certainly group by more fields, it just depends how you want to slice the results.
In your select statement you are using format like tableName.ColumnName but not for COUNT(order_id)
It should be COUNT(tableOrAlias.order_id)
Hope that helps.
As you are new to SQL it might also be worth considering the readability of your joins - the nested / bracketed joins you mentioned above are quite hard to read, and I would also personally alias your tables to make the query that bit more accessible:
SELECT
tbl_customers.customer_id
,tbl_stateprov.stprv_Name
,tbl_custstate.CustSt_Destination
,COUNT(order_id) as total
FROM tbl_stateprov statep
INNER JOIN tbl_custstate state ON statep.stprv_ID = state.CustSt_StPrv_ID
INNER JOIN tbl_customers customer ON customer.cst_ID = state.CustSt_Cust_ID
INNER JOIN tbl_orders orders ON orders.order_CustomerID = state.CustSt_Cust_ID
WHERE tbl_custstate.CustSt_Destination='BillTo'
AND cst_LastName LIKE '#URL.Alpha#%'
GROUP BY
tbl_customers.customer_id
,tbl_stateprov.stprv_Name
,tbl_custstate.CustSt_Destination
--And any other columns you want to include the count for

SQL - Left Join not working with switch statement

I am using MS Access 2007. Whenever I type Left Join, I get an error that says Left Join is not supported. Here's the SQL
TRANSFORM Count([Letter Status].Customer_ID) AS CountOfCustomer_ID
SELECT Switch(
[Race_1]=1,"White",
[Race_1]=2,"Black",
[Race_1]=3,"Asian",
[Race_1]=4,"Hispanic/Latino",
[Race_1]=5,"American Indian/ Alaskan Native",
[Race_1]=6,"Native Hawaiian or Pacific Islander",
[Race_1]=7,"Multiracial",
[Race_1]=8,"Other",
[Race_1]=9,"Unknown"
) AS Race
FROM Demographics
INNER JOIN (
[Status]
INNER JOIN
Research
ON [Status].Customer_ID = Research.Customer_ID
)
ON (Demographics.ID = [Letter Status].Customer_ID)
AND (Demographics.ID = Research.Customer_ID)
WHERE ((([Status].Count)=1))
GROUP BY [Status].Count, Demographics.Race_1
ORDER BY Research.Store_site
PIVOT Research.Store_site In (1,2,3,4,5,6,7,8,9,10);
Could someone please use the above code to show me where to place the Left Join in order to allow the rows for each Race to show in the table? Also, could you please show me how to replace Null Values with 0 in this code? I have tried to implement NZ() but have been unsuccessful.
Please help.
Look closely at your FROM clause.
FROM Demographics
INNER JOIN (
[Status]
INNER JOIN
Research
ON [Status].Customer_ID = Research.Customer_ID
)
ON (Demographics.ID = [Letter Status].Customer_ID)
AND (Demographics.ID = Research.Customer_ID)
You have an ON condition which refers to [Letter Status], but [Letter Status] isn't included among your source tables .... you do have one called [Status].
Start by building the JOINs in the query designer, so you know you're starting with SQL which Access will accept.
And simplify this thing until you get the JOINs sorted out. Get rid of Switch, TRANSFORM, PIVOT, and GROUP BY until after you have JOINs working.