salve Alberto,
alberto.picca wrote:
Ciao a tutti.
Vorrei informazioni su come si implementano le tabelle pivot.
Avrei la classica tabella CUSTOMER la cui PK é il campo ID. e in aggiunta una seconda tabella CUSTOMER_FIELD aventi dei campi chiave/valore associati al customer.
Quindi:
CUSTOMER_FIELD{
int id_customer,
int id_field_name,
string value
}
Vi chiedo, se solo attraverso sql, é possibile ottenere in colpo solo tutti i record della tabella CUSTOMER e in aggiunta le righe che sarebbero in relazione nella tabella CUSTOMER_FIELD come colonne della select.
Ho provato a cercare le tabelle PIVOT, ma sinceramente ho trovato alcune difficoltà acnhe ad implementare una semplice select.
sono solitamento contrario al modello E(ntity) A(ttribute) V(alue) come mi pare da te utilizzato.. e' tendenzialmente pericoloso se non correttamente tradotto ed implementato in una miriade di tabelle di relazionamento con i valori della tabella denormalizzata (id_field_name), come anche non assolutamente performante almeno con i dbms tradizionali che conosco, incluso SQL Server... al di la' di cio', purtroppo non puoi sfruttare le funzionalita' di pivoting in quanto non relazionate al problema.. devi quindi ricorrere ad n relazioni di join per quanti sono gli attributi che vuoi proiettare, ovvero ricorrere a n subqueries per quanti sono gli attributi stessi, similarmente a
SET NOCOUNT ON;
USE tempdb;
GO
CREATE TABLE dbo.FieldTypes (
Id int PRIMARY KEY,
Description varchar(10)
);
CREATE TABLE dbo.Customers (
Id int NOT NULL PRIMARY KEY,
);
CREATE TABLE dbo.CustomerFields (
IdCustomer int NOT NULL
CONSTRAINT fk_CustomerFields$has$Customer FOREIGN KEY
REFERENCES dbo.Customers (Id),
IdField int NOT NULL
CONSTRAINT fk_CustomerFields$has$FiledType FOREIGN KEY
REFERENCES dbo.FieldTypes (Id),
StringValue varchar(10),
CONSTRAINT pk_CustomerFields PRIMARY KEY
(IdCustomer, IdField)
);
GO
INSERT INTO dbo.FieldTypes VALUES ( 1, 'Nome' );
INSERT INTO dbo.FieldTypes VALUES ( 2, 'Citta' );
INSERT INTO dbo.FieldTypes VALUES ( 3, 'Telefono' );
INSERT INTO dbo.Customers VALUES ( 1 );
INSERT INTO dbo.Customers VALUES ( 2 );
INSERT INTO dbo.Customers VALUES ( 3 );
INSERT INTO dbo.CustomerFields VALUES ( 1, 1, 'Andrea' );
INSERT INTO dbo.CustomerFields VALUES ( 1, 2, 'Riccione' );
INSERT INTO dbo.CustomerFields VALUES ( 1, 3, '0541 111' );
INSERT INTO dbo.CustomerFields VALUES ( 2, 1, 'Alberto' );
INSERT INTO dbo.CustomerFields VALUES ( 2, 2, 'Roma' );
INSERT INTO dbo.CustomerFields VALUES ( 3, 1, 'Paolo' );
INSERT INTO dbo.CustomerFields VALUES ( 3, 3, '02 123' );
GO
PRINT 'utilizzo di join';
SELECT c.Id,
N.StringValue AS [Nome],
citta.StringValue AS [Citta],
T.StringValue AS [Telefono]
FROM dbo.Customers c
LEFT JOIN dbo.CustomerFields N
ON N.IdCustomer = c.Id AND N.IdField = 1
LEFT JOIN dbo.CustomerFields citta
ON citta.IdCustomer = c.Id AND citta.IdField = 2
LEFT JOIN dbo.CustomerFields T
ON T.IdCustomer = c.Id AND T.IdField = 3
ORDER BY c.Id;
PRINT '';
PRINT 'utilizzo di subqueries';
SELECT c.Id,
(SELECT cf.StringValue
FROM dbo.CustomerFields cf
WHERE cf.IdCustomer = c.Id
AND cf.IdField=1
) AS [Nome],
(SELECT cf.StringValue
FROM dbo.CustomerFields cf
WHERE cf.IdCustomer = c.Id
AND cf.IdField=2
) AS [Citta],
(SELECT cf.StringValue
FROM dbo.CustomerFields cf
WHERE cf.IdCustomer = c.Id
AND cf.IdField=3
) AS [Telefono]
FROM dbo.Customers c
ORDER BY c.Id;
GO
DROP TABLE dbo.CustomerFields, dbo.Customers, dbo.FieldTypes; --<-------
utilizzo di join
Id Nome Citta Telefono
---------
--------
--------
----------
1 Andrea Riccione 0541 111
2 Alberto Roma NULL
3 Paolo NULL 02 123
utilizzo di subqueries
Id Nome Citta Telefono
---------
--------
--------
----------
1 Andrea Riccione 0541 111
2 Alberto Roma NULL
3 Paolo NULL 02 123
il disegno del modello, nella sua disarmante semplicita', e' ovviamente da incubo...
personalmente ti vorrei scoraggiare dal suo utilizzo..
saluti