Understanding Unnamed Column in SQL Select Statement Results - sql

I am more familiar with a MongoDB architecture than sql. A colleague passed this query to me in order to get some data out of sybase:
SELECT order_items.contracted_rate FROM customers
JOIN orders
ON orders.customers_id = customer.id_number
JOIN order_items
ON order_items.order_id = orders.id,
ORDER by customer.id_number
When I run this query I get data that looks like this:
contracted_rate
1 | 20
2 | 14
3 | 18
My question is, what are the left-side numbers pertaining to from the above query? In other words, how can I map these item numbers (1, 2, 3) to a sybase table?
I'm used to seeing something more like this after running a sybase query:
id contracted_rate
1 | 20
2 | 14
3 | 18
So I'm trying to understand what the unnamed column refers to, and how I can map it to a sybase table to match up the correct customers?

Assuming this is the customerID you need, you can do this. The Id you show is not part of the result set
SELECT customer.id_number, order_items.contracted_rate
FROM customers
JOIN orders
ON orders.customers_id = customer.id_number
JOIN order_items
ON order_items.order_id = orders.id,
ORDER by customer.id_number

Related

SQL Selecting & Counting In the same query

thanks in advance for any help on this, I am a bit of a newbie to MS SQL and I want to do something that I think is achievable but don't have the know how.
I have a simple table called "suppliers" where I can do (SELECT id, name FROM suppliers ORDER BY id ASC)
id
name
1
ACME
2
First Stop Business Supplies
3
All in One Supply Warehouse
4
Farm First Supplies
I have another table called "products"
id
name
supplier_id
1
Item 1
2
2
Item 2
1
3
Item 3
1
4
Item 4
3
5
Item 5
2
I want to list all the suppliers and get the total amount of products for each supplier if that makes sense on the same row? I am just not sure how to pass the suppliers.id through the query to get the count.
I am hoping to get to this:
id
name
total_products
1
ACME
2
2
First Stop Business Supplies
2
3
All in One Supply Warehouse
1
4
Farm First Supplies
0
I really appreciate any help on this.
Three concepts to grasp here. Left Join, group by, and Count().
select s.id, s.name, Count(*) as total_products
from suppliers s
left join products p on s.id=p.supplier_id --the left join gets your no matches
group by s.id, s.name
left join is a join where all of the values from the first table are kept even if there are no matches in the second.
Group by is an aggregation tool where the columns to be aggregated are entered.
Count() is simply a count of transactions for the grouped columns.
Try this :-
SELECT id, name, C.total_products
FROM Suppliers S
OUTER APPLY (
SELECT Count(id) AS total_products
FROM Products P
WHERE P.supplier_id = S.id
) C

Join table using column value as table name

Is it possible to join a table whereby the table name is a value in a column?
Here is a TABLE called food:
id food_name price_table pricing_reference_id
1 | 'apple' | 'daily_price' | 13
2 | 'banana' | 'monthly_price' | 13
3 | 'hotdog' | 'weekly_price' | 17
4 | 'sandwich' | 'monthly_price' | 9
There are three other tables (pricing tables): daily_price, weekly_price, and monthly_price tables.
Side note: Despite their names, the three pricing tables display vastly different kinds of information, which is why the three tables were not merged into one table
Each row in the food table can only be joined with one of the three pricing tables at most.
The following does not work -- it is just to illustrate what I am trying to get at:
SELECT *
FROM food
LEFT JOIN food.price_table ON food.pricing_reference_id = daily_price.id
WHERE id = 1;
Obviously the query does not work. Is there any way that the name of the table in the price_table column could be used as the table name in a join?
I would suggest left joins:
select f.*,
coalesce(dp.price, wp.price, mp.price) as price
from food f left join
daily_price dp
on f.pricing_reference_id = dp.id and
f.pricing_table = 'daily_price' left join
weekly_price wp
on f.pricing_reference_id = wp.id and
f.pricing_table = 'weekly_price' left join
monthly_price mp
on f.pricing_reference_id = mp.id and
f.pricing_table = 'monthly_price' ;
For the columns you reference, you need to use coalesce() to combine the results from the three tables. You say that the tables have different data, so you would need to list the columns separately.
The main reason I recommend this approach is performance. I think the left joins should be faster than any solution that uses union all.
Could you get your expected result using by a derived table with UNION SELECT which has a column of each table name?
SELECT *
FROM food
LEFT JOIN
(
SELECT 'daily_price' AS price_table, * FROM daily_price
UNION ALL SELECT 'monthly_price', * FROM monthly_price
UNION ALL SELECT 'weekly_price', * FROM weekly_price
) t
ON food.price_table = t.price_table AND
food.pricing_reference_id = t.id
ORDER BY food.id;
dbfiddle

SQL to fetch Data from 2 tables only using Join where we need empty records from second table as well

We have a situation in which one part of our stored procedure need to be filled with a join query, which had multiple filters in it. We need a solution only with join (it is easy to implement in the subquery, but our situation demands it to be a join [since the procedure has a where clause followed by it] )
We have two tables Customer and Order. We need to exclude the rows of Customer table, if Customer_id is present Order table & order_code = 10 & Customer.Grade = 3. It is not mandatory for all Customer_id to be present in Order table, but we still need it in the final result.
Customer Table OrderTable
Customer_id Grade Customer_id order_code
1 3 1 10
2 3 1 40
3 2 2 50
4 3 3 30
*Multiple Customer_id can be present in the OrderTable
Expected result :
Customer_id Grade
2 3
3 2
4 3
I think this may be what you need, not sure I understand the question properly.
select c.id, c.grade
from customer c left join customer_order o on (c.id = o.customer_id and o.order_code <> 10)
where c.grade = 3
This should give you all customers with a Grade of 3 that also have orders, provided the order_code is not 10. If you want to show customers that do not have any orders also, make it a left join.
You can express the logic like this:
select c.*
from customers c
where not (grade = 3 and
exists (select 1
from orders o
where o.customer_id = c.customer_id and
o.order_code = 10
)
);

SQL Lookup data in joined table based on LIKE value stored in joined table column

I am trying to build a query that will look up a product_subcategory based on a reference data in a user entered table and joining two tables together. My database is SQL Server 2012 Express.
First the products table has three columns: Product_id (unique identifier), event_id (INT data type), and product_category. (product_category needs to be alphanumeric currently varchar(32) data type)
Example Products table data:
Product_id event_id product_category
1 20 100
2 20 105
3 20 200
4 21 100
5 21 200
6 21 203
7 22 105
8 22 207
Second the events table has two columns: event_id (unique identifier, INT Data type) and zone (float data type, not sure why this was setup as float, probably should have been INT but its a pre-existing table and I don't want to change it)
event_id zone
20 1
21 2
22 3
Third the subcategory table has four columns: subcategory_id (unique identifier, INT data type), zone (joins to zone column in products table, INT Data type), category_lookup (varchar(max) data type), and product_subcategory (varchar(50) data type). This is a table that I am creating for this project so I can change the structure or datatypes to be whatever is needed for the project, I don't have that flexibility on the other tables.
Example Subcategory table data:
subcategory_id zone category_lookup product_subcategory
1 1 '1%' 25
2 1 '2%' 23
3 2 '1%' 26
4 2 '2%' 30
I want to build a query that will search the product table and match a zone, product_category, and product_subcategory together based on the value in the subcategory.category_lookup column.
The data that I want returned from the query is:
product_ID zone product_category product_subcategory
1 1 100 25
2 1 105 25
3 1 200 23
4 2 100 26
5 2 200 30
6 2 203 30
7 3 105 NULL or 'N/A'
8 3 107 NULL or 'N/A'
The logic behind looking up the matching subcategory will be similar to below: (this is essentially what is stored in the subcategory table) (the text in the “quotes” is what I mean by reference data, and will be user entered)
IE... if zone = 1 and product_category “begins with 1” then product_subcategory = 25
IE... if zone = 1 and product_category “begins with 2” then product_subcategory = 23
IE... if zone = 2 and product_category “begins with 1” then product_subcategory = 26
IE... if zone = 2 and product_category “begins with 2” then product_subcategory = 30
I do understand that one of the issues with my logic is that if multiple subcategories match to one product then it will throw an error, but I think I can code around that once I get this part of it working
I am fine going a different direction with this project but this is the first way I decided to tackle it. The most important component is that the product_subcategory’s are going to be located in a separate user entered table, and there needs to be user entered logic as discussed above to determine the product_subcategory based on zone and product_category.
I am not a SQL guru at all so I don’t even know where to start to handle this problem. Any advice is appreciated.
Based on answers I have received so far I have come up with this:
SELECT p.product_id, p.event_id, e.zone, p.product_category, sc.product_subcategory
FROM Products p
LEFT JOIN events e on p.event_id = e.event_id
LEFT JOIN SubCategory sc ON e.zone = sc.zone AND CAST(p.product_category as varchar(max)) like sc.category_lookup
But unfortunately its only returning NULL for all of the product_subcategory results.
Any additional help is appreciated.
Thanks,
This should do the trick, you will just need to modify the CAST(p.zone as nchar(10)) to insert the correct data type for your category_lookup column, in place of nchar(10), as I assume the zone in Products is an int where as the lookup column is some string based column:
SELECT p.product_id, p.zone, p.product_category, sc.product_subcategory
FROM Products p
LEFT JOIN SubCategory sc ON p.zone = sc.zone
AND CAST(p.zone as nchar(10)) like sc.category_lookup
Based on your updates, the following should work:
SELECT p.product_id, p.event_id, e.zone, p.product_category,
sc.product_subcategory
FROM Products p
INNER JOIN events e on p.event_id = e.event_id
LEFT OUTER JOIN SubCategory sc ON e.zone = sc.zone
AND CAST(e.zone as nchar(250)) LIKE CAST(sc.category_lookup as nchar(250))
Update based on comments:
SELECT p.product_id, p.event_id, e.zone, p.product_category,
sc.product_subcategory
FROM Products p
INNER JOIN events e on p.event_id = e.event_id
LEFT OUTER JOIN SubCategory sc ON e.zone = sc.zone
AND CAST(p.product_category as nchar(250)) LIKE sc.category_lookup
Working sample SQLFiddle
Not tested but is this what you're looking for ?
select a.product_ID, a.zone, a.product_category, b.product_subcategory
from Products a
inner join Subcategory on ((a.zone = b.zone) and (a.product_category like b.category_lookup))
Try this..
select p.product_id, p.zone, p.product_category, isnull(s.product_subcategory,'NA') as product_subcategory
from Products p
left outer join Subcategory s on (s.zone = p.zone and p.product_category like s.category_lookup);

Sql create a table based on a cell value

I have a problem where I have tables that are created based on the date & time, this table is created in a SP that I didn't write. In any event need to get a count of these tables every time they are created.
What I have done so far is create a table that has these names, and added a Count field.
Table looks like this and is called SP.DBO.AUSEMAIL
SourceTable Count
SP.DBO.VIP_BPAU_00030_20130531_092027
SP.DBO.ADV_BPAU_00030_20130531_092027
Now basically I need to create a query that will give me a count of SP.DBO.VIP_BPAU_00030_20130531_092027 and SP.DBO.ADV_BPAU_00030_20130531_092027 and populate the above table.
As I will not know what the table will be called every day, and am working towards fully automating this I can't just to counts of each of these files.
I have tried something like this and am getting nowhere.
select count(*)
from top 1 (select sourcetable
from SP.DBO.AUSEMAIL
where source_table like 'SP.DBO.VIP_BPAU%')
Any ideas would be very helpful.
To update count column in your ausemail table
UPDATE a
SET a.count = i.rowcnt
FROM sysindexes AS i INNER JOIN sysobjects AS o
ON i.id = o.id JOIN ausemail a
ON o.name = a.source_table
If you know exactly the pattern you can do something like this
SELECT o.name source_table,
i.rowcnt count
FROM sysindexes AS i INNER JOIN sysobjects AS o
ON i.id = o.id
WHERE o.name LIKE '___!_BPAU!_%' ESCAPE '!' -- < adjust the pattern as needed
Sample output:
| SOURCE_TABLE | COUNT |
------------------------------------------
| VIP_BPAU_00030_20130531_092027 | 4 |
| ADV_BPAU_00030_20130531_092027 | 2 |
Here is SQLFiddle demo.