Need some help making this work please. Some help please to ensure I always return just one row per ProductID. My Product Table contains base information on Products which can be properties in this case. It links to the Properties table via a ProductCode.
What I would like is to have the query return just the one row which it really should. Essentially, the row should display the PropertyLabel whether or not there are values in the PropertyProductValues table for that particular propertyLabel. The code below returns a bunch of rows which really it shouldn't, or I don't want it to. And I would appreciate help fine tuning this please. thanks in Advance.
Create Table Product
{
ProductID uniqueidentifier,
ProductName Varchar(50),
ProductCode Varchar(50)
}
Create Table Properties
{
PropertyID uniqueidentifier,
PropertyProductcode Varchar(50)
}
Create Table PropertyProductValues
{
ID uniqueidentifier,
PropertyID uniqueidentifier,
ProductID uniqueidentifier,
PropertyLabel Varchar(50),
UnitID uniqueidentifier
}
Create Table unit
{
UnitID uniqueidentifier,
Unit Varchar(50)
}
Select productid , PropertyLabel
PropertyValue
PropertyUnit
from Product
inner join Properties on ProductCode = PropertyProductCode
left join PropertyProductValues on Properties.PropertyID = ProductProductValues.PropertyID
left join Unit on PropertyValues.UnitID = Unit.UnitID
Where ltrim(rtrim(lower(PropertyLabel))) = lower('Special')
Sample Data
Product Table
b0359c76-8622-4006-82f2-1b4c91a8f6b3 Brown Building YSHJT
aba475c4-5a5c-483a-9faa-67f67ff9672d Sket Building GTJHD54
8f645348-8871-4fad-8c85-9fc6a1169b33 HOUSE 9 DGFS345
Properties Table
27c6485b-f7a5-4243-9304-71939230964d DGFS345
88e911e5-bf40-4f14-89cc-4ed2984c342e GTJHD54
d217cc14-6fcb-4251-a6d7-8fd1b3398a32 YSHJT
689cfd9d-bc87-4e23-afb3-d6cbf1e961f6 FFFSRW
bf7ae151-2e3f-4e0a-bf8b-d44ef30cf276 WYSJD
PropertyProductValues Table
6cf47434-c834-455d-a606-3d10cb9f7ab3 b0359c76-8622-4006-82f2-1b4c91a8f6b3 b0359c76-8622-4006-82f2-1b4c91a8f6b3 Storey
82ee0f80-afe4-45c2-877c-e79ce286170f 27c6485b-f7a5-4243-9304-71939230964d b0359c76-8622-4006-82f2-1b4c91a8f6b3 Bedrooms
5ff7f809-6b1f-4d6c-a125-29ce67f097d7 27c6485b-f7a5-4243-9304-71939230964d 8f645348-8871-4fad-8c85-9fc6a1169b33 Bathrooms
7f634b81-1212-4223-af42-29b4dc2bafcc 27c6485b-f7a5-4243-9304-71939230964d aba475c4-5a5c-483a-9faa-67f67ff9672d Material
cae10884-edf0-4340-bde6-5207e28a07cc 689cfd9d-bc87-4e23-afb3-d6cbf1e961f6 b0359c76-8622-4006-82f2-1b4c91a8f6b3 Basement
83943759-39d7-406e-92ea-4202a9b1d716 bf7ae151-2e3f-4e0a-bf8b-d44ef30cf276 b0359c76-8622-4006-82f2-1b4c91a8f6b3 Storey
c045d0ff-34db-4427-9fb7-fd41fc92f310 bf7ae151-2e3f-4e0a-bf8b-d44ef30cf276 aba475c4-5a5c-483a-9faa-67f67ff9672d balcony
Unit Table
UNITID UNIT
3a4a5216-0704-495e-b0a7-560787e0847a kg
6b4493f6-c2e4-4682-b71d-93cb1893eb73 m
2f2b4fee-9e69-4a71-a098-36e2da71471e l
55c8e5bf-edde-4977-ab7b-8827e337a31e oz
19528647-bd9f-48e0-ba86-b722d5b8ab0e cm
cee5cd46-1ae4-4b49-8b1c-9b3e0bd5270f mm
It would help if you gave the table structure of your 3 tables, but in principle, to get 1 row per PropertyId, you'll be doing a GROUP BY PropertyId.
Related
So I have 3 tables called Books, Listings and Orders that can be seen in the code sample. My problem is that I want to display listings on the frontend, except I want to omit the listings that already have an order attached to it. Should I add an "ordered" boolean to Listings? Is the foreign key from orders to listings appropriate?
Also, if I want to look at fulfilled orders, there is a problem if a listing is removed and it had a foreign key connected to a fulfilled order. How to I design that?
Table books{
id int [pk, increment]
title varchar
isbn10 varchar
amazon_used_price int
edition varchar
image varchar
}
Table listings{
id int [pk, increment]
price int
date_listed datetime
seller_email varchar
book_id int [ref: > books.id]
}
Table orders{
id int [pk, increment]
completed boolean
buyer_email varchar
listing_id int [ref: > listings.id]
}
You shouldn't add an ordered column as that will cause many more problems than it will fix: concurrency being one of them.
Instead you can select your listings and exclude ones that have orders:
SELECT b.title, b.isbn10, b.amazon_used_price,b.edition, b.image,
l.id, l.price, l.date_listed, l.seller_email
FROM listings l LEFT JOIN books b ON l.book_id = b.id
LEFT JOIN orders o ON l.id = o.listing_id
WHERE IS NULL o.id
ORDER BY b.title, b.isbn10
I assumed a few things, including the order of the records you want, but you should get the idea from this.
I am hoping someone can help me with this SQL view.
I have a screen where you can add products to an order. This order is for a customer which may or may not have a special price for the item.
Essentially, I am after 3 figures:
The unit price for the product as input by the operator
The default price for the product (standard ratecard)
The special price for the client for this product (may not exist)
To simplify things, I have the following tables
OrderLine
OrderId
ProductId
ProductVariationId (can be null)
Ratecard
RatecardId
RatecardName
RatecardClient (Default master ratecard is ID 1)
RatecardClientId
RatecardId
ClientId
RatecardProduct
RatecardProductId
ProductId
ProductVariationId (can be null)
A product has an ID but can also have a product variation ID
I want to create a view for OrderLine which has the input price, the default ratecard price and the special price for that product.
I would like a view which gives me:
Product Id
UnitPrice From "OrderLine"
RatecardPrice From "RatecardProduct" relating to "Ratecard" with RatecardId = 1 (will always exist)
ClientRatecardPrice (Depends if there is an existing ratecard and entry in this ratecard for the client / product / variation )
I'm really hoping someone can get me started here as I'm really struggling!
Thank you in advance!
I have made some assumptions about where the price columns are, and also how the RateCardProduct joins to RateCard. It would be better if you included the actual table definitions with extra columns stripped out. But with the assumptions you can see in my table defs, this query should give you what you want.
create table ClientOrder(OrderID int, ClientID int)
create table OrderLine(OrderId int,ProductId int,ProductVariationId int, UnitPrice decimal(10,2))
create table Ratecard(RateCardId int,RatecardName varchar(50)) -- has default 1
create table RateCardClient(RatecardClientId int,RatecardId int,ClientId int)
create table RateCardProduct(RatecardProductId int, RateCardId int, ProductId int, ProductVariationId int, Price decimal(10,2))
select Clientorder.ClientID, ClientOrder.OrderID, OrderLine.ProductID, OrderLine.ProductVariationId,
OrderLine.UnitPrice as UnitPrice,
P1.Price as RateCardPrice,
P2.Price as ClientRateCardPrice
from ClientOrder
Join OrderLine on OrderLine.OrderID=ClientOrder.OrderID
-- Get the default price
join RateCardProduct P1 on P1.RateCardID=1
and P1.ProductId=OrderLine.ProductId
and isnull(P1.ProductVariationID,0)=isnull(OrderLine.ProductVariationID,0)
-- Get the customer specific price
left join RateCardClient on RateCardClient.ClientID=ClientOrder.ClientID
left join RateCardProduct P2 on P2.RateCardID=RateCardClient.RateCardID
and P2.ProductId=OrderLine.ProductId
and isnull(P2.ProductVariationID,0)=isnull(OrderLine.ProductVariationID,0)
I would like to create a product table. This product has unique part numbers. However, each part number has various number of previous part numbers, and various number of machines where the part can be used.
For example the description for part no: AA1007
Previous part no's: AA1001, AA1002, AA1004, AA1005,...
Machine brand: Bosch, Indesit, Samsun, HotPoint, Sharp,...
Machine Brand Models: Bosch A1, Bosch A2, Bosch A3, Indesit A1, Indesit A2,....
I would like to create a table for this, but I am not sure how to proceed. What I have been able to think is to create a table for Previous Part no, Machine Brand, Machine Brand Models individually.
Question: what is the proper way to design these tables?
There are of course various ways to design the tables. A very basic way would be:
You could create tables like below. I added the columns ValidFrom and ValidTill, to identify at which time a part was active/in use.
It depends on your data, if datatype date is enough, or you need datetime to make it more exactly.
CREATE TABLE Parts
(
ID bigint NOT NULL
,PartNo varchar(100)
,PartName varchar(100)
,ValidFrom date
,ValidTill date
)
CREATE TABLE Brands
(
ID bigint NOT NULL
,Brand varchar(100)
)
CREATE TABLE Models
(
ID bigint NOT NULL
,BrandsID bigint NOT NULL
,ModelName varchar(100)
)
CREATE TABLE ModelParts
(
ModelsID bigint NOT NULL
,PartID bigint NOT NULL
)
Fill your data like:
INSERT INTO Parts VALUES
(1,'AA1007', 'Screw HyperFuturistic', '2017-08-09', '9999-12-31'),
(1,'AA1001', 'Screw Iron', '1800-01-01', '1918-06-30'),
(1,'AA1002', 'Screw Steel', '1918-07-01', '1945-05-08'),
(1,'AA1004', 'Screw Titanium', '1945-05-09', '1983-10-05'),
(1,'AA1005', 'Screw Futurium', '1983-10-06', '2017-08-08')
INSERT INTO Brands VALUES
(1,'Bosch'),
(2,'Indesit'),
(3,'Samsung'),
(4,'HotPoint'),
(5,'Sharp')
INSERT INTO Models VALUES
(1,1,'A1'),
(2,1,'A2'),
(3,1,'A3'),
(4,2,'A1'),
(5,2,'A2')
INSERT INTO ModelParts VALUES
(1,1)
To select all parts of a certain date (in this case 2013-03-03) of the "Bosch A1":
DECLARE #ReportingDate date = '2013-03-03'
SELECT B.Brand
,M.ModelName
,P.PartNo
,P.PartName
,P.ValidFrom
,P.ValidTill
FROM Brands B
INNER JOIN Models M
ON M.BrandsID = B.ID
INNER JOIN ModelParts MP
ON MP.ModelsID = M.ID
INNER JOIN Parts P
ON P.ID = MP.PartID
WHERE B.Brand = 'Bosch'
AND M.ModelName = 'A1'
AND P.ValidFrom <= #ReportingDate
AND P.ValidTill >= #ReportingDate
Of course there a several ways to do an historization of data.
ValidFrom and ValidTill (ValidTo) is one of my favourites, as you can easily do historical reports.
Unfortunately you have to handle the historization: When inserting a new row - in example for your screw - you have to "close" the old record by setting the ValidTill column before inserting the new one. Furthermore you have to develop logic to handle deletes...
Well, thats a quite large topic. You will find tons of information in the world wide web.
For the part number table, you can consider the following suggestion:
id | part_no | time_created
1 | AA1007 | 2017-08-08
1 | AA1001 | 2017-07-01
1 | AA1002 | 2017-06-10
1 | AA1004 | 2017-03-15
1 | AA1005 | 2017-01-30
In other words, you can add a datetime column which versions each part number. Note that I added a primary key id column here, which is invariant over time and keeps track of each part, despite that the part number may change.
For time independent queries, you would join this table using the id column. However, the part number might also serve as a foreign key. Off the top of my head, if you were generating an invoice from a previous date, you might lookup the appropriate part number at that time, and then join out to one or more tables using that part number.
For the other tables you mentioned, I do not see a similar requirement.
I'm banging my head on this SQL puzzle since a couple of hours already, so i thought to myself : "Hey, why don't you ask the Stack and allow the web to benefit from the solution?"
So here it is. First thing, these are my SQL tables:
Fields
FieldID INT (PK)
FieldName NVARCHAR(50) (IX)
FormFields
FieldID INT (FK)
FormID INT (FK)
Values
FieldID INT (FK)
RecordID INT (FK)
Value NVARCHAR(1000)
Forms
FormID INT (PK)
FormName NVARCHAR(50) (IX)
Records
RecordID INT (PK)
FormID INT (FK)
PoolID INT (FK)
DataPools
PoolID INT (PK)
FormID INT (FK)
PoolName NVARCHAR(50) (IX)
Consider the following constraints.
Each Form has 0 or more DataPool. Each DataPool can only be assigned to one Form.
Each Form has 0 or more Field. Each Field might be assigned to several Form.
Each Record has 0 or more Value. Each Value is linked to a single Record.
Each DataPool has 0 or more Record. Each Record is linked to a single DataPool.
Each Value is linked to one Field.
Also, all the Name columns have unique values.
Now, here's the problem:
I need to query evey value form the Values table based on the following columns:
The Name of the Field linked to the Value
The Name of the DataPool linked the Record linked to the Value
The Name of the Form linked to that DataPool
The 3 columns above must be equal to the 3 received parameters in the stored procedure.
Here's what I got so far:
CREATE PROCEDURE [GetValues]
#FieldName NVARCHAR(50),
#FormName NVARCHAR(50),
#PoolName NVARCHAR(50)
AS SELECT Value FROM [Values]
JOIN [Fields]
ON [Fields].FieldID = [Values].FieldID
WHERE [Fields].FieldName = #FieldName
How can I filter the rows of the Values table by the PoolName column? The DataPools table isn't directly related to the Values table, but it's still related to the Records table which is directly related to the Values table. Any ideas on how to do that?
I feel like I am missing something in your question. If this solution is not addressing the problem, please let me know where it is missing the issue.
SELECT
Values.Value
FROM
Values INNER JOIN Fields ON
Values.FieldId = Fields.FieldId
INNER JOIN FormFields ON
Fields.FieldId = FormFields.FieldId
INNER JOIN Forms ON
FormFields.FormId = Forms.FormId
INNER JOIN DataPools ON
Forms.FormId = DataPools.FormId
WHERE
Fields.FieldName = #FieldName
AND
Forms.FormName = #FormName
AND
DataPools.PoolName = #PoolName;
if i understand what your needing this should work just fine.
select * from
values v
join records r
on v.recordid = r.recordid
join datapool dp
on r.poolid = dp.poolid
join forms f
on r.formid = f.formid
join fields fi
on v.fieldid = fi.fieldid
where
fi.FieldName = #FieldName
AND
f.FormName = #FormName
AND
dp.PoolName = #PoolName;
I have a column groups. Groups has different type stored in group_types (buyers, sellers, referee). Only when the group is of type buyer it has another type (more specialized) like electrical and mechanical.
I'm a bit puzzled with how I will store this in a database.
Someone can suggest me a database structure?
thanks
Store your group_types as a hieararchical table (with nested sets or parent-child model):
Parent-child:
typeid parent name
1 0 Buyers
2 0 Sellers
3 0 Referee
4 1 Electrical
5 1 Mechanic
SELECT *
FROM mytable
WHERE group IN
(
SELECT typeid
FROM group_types
START WITH
typeid = 1
CONNECT BY
parent = PRIOR typeid
)
will select all buyers in Oracle.
Nested sets:
typeid lower upper Name
1 1 2 Buyers
2 3 3 Sellers
3 4 4 Referee
4 1 1 Electrical
5 2 2 Mechanic
SELECT *
FROM group_types
JOIN mytable
ON group BETWEEN lower AND upper
WHERE typeid = 1
will select all buyers in any database.
Nested sets is implementable anywhere and more performant, if you don't need hierarchical ordering or frequent updates on group_types.
Parent-child is implementable easily in Oracle and SQL Server and with a little effort in MySQL. It allow easy structure changing and hierarchical ordering.
See this article in my blog on how to implement it in MySQL:
Hierarchical queries in MySQL
You could possibly store additional types like, buyer_mechanical or buyer_electrical.
You could try:
Group
group_id
group_name
group_parent_id
with entries (1, buyers, 0), (2, sellers, 0), (3, referee, 0), (4, electrical, 1), (5, mechanical, 1)
This has the advantage of being infinitely scalable, so each subgroup can have as many subgroups as you want.
Typically, you have extension tables. These are simply additional tables in your schema which hold additional information linked to the main table by some type of key
For example let's say your main table is:
People
PersonId int, PK
GroupTypeId int, FK to GroupTypes
Name varchar(100)
GroupTypes
GroupTypeId int, PK
GroupTypeName varchar(20)
BuyerTypes
BuyerTypeId int, PK
BuyerTypeName varchar(20)
BuyerData
PersonId int, FK
BuyerTypeId int FK
====
Additionally, the BuyerData would have a composite primary key (PK) on PersonId and BuyerTypeId
When pulling Buyer data out, you could use a query like
SELECT *
FROM People P
INNER JOIN BuyerData BD on (P.PersonId = BD.PersonId)
INNER JOIN BuyerTypes BT on (BD.BuyerTypeId = BT.BuyerTypeId)
grouptype: ID, Name ('buyers', 'sellers', 'referee')
group: GroupTypeID, ID, Name ('electrical' and 'mechanical' if grouptypeid == 'buyers')
contact: GroupTypeID (NOT NULL), GroupID (NULL), other attributes
Table Group is populated with records for GroupTypes as required.
Contact.GroupID can be NULL since a GroupType need not have any Groups.
UI has to take care of Group selection. You can have a trigger check the group/type logic.