croce sql iscriversi - a che serve qualcuno ha trovato per esso? [chiuso]
-
22-08-2019 - |
Domanda
Oggi, per la prima volta in 10 anni di sviluppo con sql server ho usato un cross join in una query di produzione. Avevo bisogno di pad un set di risultati di una relazione e ha scoperto che un cross join tra due tabelle con un creativo in cui la clausola è stata una buona soluzione. Mi chiedevo che cosa serve qualcuno ha trovato nel codice di produzione per il cross join?
Aggiornamento: il codice pubblicato da Tony Andrews è molto vicino a quello che ho usato il cross join per. Mi creda, capisco le implicazioni dell'utilizzo di un cross join e non lo farei con tanta leggerezza. Ero entusiasta di avere finalmente usato (io sono un secchione) - un po 'come il tempo che ho prima usato un full outer join.
Grazie a tutti per le risposte! Ecco come ho usato i cross join:
SELECT CLASS, [Trans-Date] as Trans_Date,
SUM(CASE TRANS
WHEN 'SCR' THEN [Std-Labor-Value]
WHEN 'S+' THEN [Std-Labor-Value]
WHEN 'S-' THEN [Std-Labor-Value]
WHEN 'SAL' THEN [Std-Labor-Value]
WHEN 'OUT' THEN [Std-Labor-Value]
ELSE 0
END) AS [LABOR SCRAP],
SUM(CASE TRANS
WHEN 'SCR' THEN [Std-Material-Value]
WHEN 'S+' THEN [Std-Material-Value]
WHEN 'S-' THEN [Std-Material-Value]
WHEN 'SAL' THEN [Std-Material-Value]
ELSE 0
END) AS [MATERIAL SCRAP],
SUM(CASE TRANS WHEN 'RWK' THEN [Act-Labor-Value] ELSE 0 END) AS [LABOR REWORK],
SUM(CASE TRANS
WHEN 'PRD' THEN [Act-Labor-Value]
WHEN 'TRN' THEN [Act-Labor-Value]
WHEN 'RWK' THEN [Act-Labor-Value]
ELSE 0
END) AS [ACTUAL LABOR],
SUM(CASE TRANS
WHEN 'PRD' THEN [Std-Labor-Value]
WHEN 'TRN' THEN [Std-Labor-Value]
ELSE 0
END) AS [STANDARD LABOR],
SUM(CASE TRANS
WHEN 'PRD' THEN [Act-Labor-Value] - [Std-Labor-Value]
WHEN 'TRN' THEN [Act-Labor-Value] - [Std-Labor-Value]
--WHEN 'RWK' THEN [Act-Labor-Value]
ELSE 0 END) -- - SUM([Std-Labor-Value]) -- - SUM(CASE TRANS WHEN 'RWK' THEN [Act-Labor-Value] ELSE 0 END)
AS [LABOR VARIANCE]
FROM v_Labor_Dist_Detail
where [Trans-Date] between @startdate and @enddate
--and CLASS = (CASE @class WHEN '~ALL' THEN CLASS ELSE @class END)
GROUP BY [Trans-Date], CLASS
UNION --REL 2/6/09 Pad result set with any missing dates for each class.
select distinct [Description] as class, cast([Date] as datetime) as [Trans-Date], 0,0,0,0,0,0
FROM Calendar_To_Fiscal cross join PRMS.Product_Class
where cast([Date] as datetime) between @startdate and @enddate and
not exists (select class FROM v_Labor_Dist_Detail vl where [Trans-Date] between @startdate and @enddate
and vl.[Trans-Date] = cast(Calendar_To_Fiscal.[Date] as datetime)
and vl.class= PRMS.Product_Class.[Description]
GROUP BY [Trans-Date], CLASS)
order by [Trans-Date], CLASS
Soluzione
Un uso che ho incontrato un sacco è record spaccare fuori in diversi record, principalmente per scopi di segnalazione.
Immaginate una stringa in cui ogni carattere rappresenta un evento nel corrispondente ore.
ID | Hourly Event Data
1 | -----X-------X-------X--
2 | ---X-----X------X-------
3 | -----X---X--X-----------
4 | ----------------X--X-X--
5 | ---X--------X-------X---
6 | -------X-------X-----X--
Ora si vuole un rapporto che mostra come molti eventi accaduti in quale giorno. Croce si uniscono al tavolo con una tabella di ID da 1 a 24, poi lavorare la tua magia ...
SELECT
[hour].id,
SUM(CASE WHEN SUBSTRING([data].string, [hour].id, 1) = 'X' THEN 1 ELSE 0 END)
FROM
[data]
CROSS JOIN
[hours]
GROUP BY
[hours].id
=>
1, 0
2, 0
3, 0
4, 2
5, 0
6, 2
7, 0
8, 1
9, 0
10, 2
11, 0
12, 0
13, 2
14, 1
15, 0
16, 1
17, 2
18, 0
19, 0
20, 1
21, 1
22, 3
23, 0
24, 0
Altri suggerimenti
Un tipico utilizzo legittimo di un cross join sarebbe un rapporto che mostra esempio vendite totali per prodotto e regione. Se nessuna vendita sono state fatte di prodotto P nella regione R poi vogliamo vedere una riga con uno zero, piuttosto che semplicemente non mostrando una fila.
select r.region_name, p.product_name, sum(s.sales_amount)
from regions r
cross join products p
left outer join sales s on s.region_id = r.region_id
and s.product_id = p.product_id
group by r.region_name, p.product_name
order by r.region_name, p.product_name;
Ho diversi rapporti che Prefiltro il set di record (da varie linee di business all'interno della società), ma c'erano i calcoli che richiedevano percentuali di entrate ditta-larga. Il recordsource doveva contenere il totale fermo, invece di basarsi sul calcolo della somma complessiva nella relazione stessa.
Esempio: Il recordset ha saldi per ogni cliente e la Line of Business entrate del cliente proviene. La relazione può mostrare solo clienti al dettaglio. Non v'è alcun modo per ottenere una somma dei saldi per l'intera azienda, ma il rapporto mostra la percentuale delle entrate della società.
Dato che ci sono diversi campi di equilibrio, ho sentito che era meno complicato di avere piena unirsi con la vista che ha diversi saldi (posso anche riutilizzare questo punto di vista dei totali impresa) al posto del più campi costituiti da query sub.
Un altro è un'istruzione di aggiornamento dove più record dovevano essere creato (un record per ogni fase di un processo di workflow prestabilito).
Ecco uno, dove il CROSS JOIN sostituti per un INNER JOIN. Ciò è utile e legittimo quando non ci sono valori identici tra due tabelle su cui aderire. Ad esempio, si supponga di avere una tabella che contiene la versione 1, versione 2 e la versione 3 di qualche documento dichiarazione o la società, il tutto salvato in una tabella di SQL Server in modo che è possibile ricreare un documento che è associato con un ordine, al volo, molto tempo dopo l'ordine, e molto tempo dopo il documento è stato riscritto in una nuova versione. Ma solo uno dei due tavoli è necessario iscriversi (la tabella Documenti) ha una colonna VERSIONID. Ecco un modo per farlo:
SELECT DocumentText, VersionID =
(
SELECT d.VersionID
FROM Documents d
CROSS JOIN Orders o
WHERE o.DateOrdered BETWEEN d.EffectiveStart AND d.EffectiveEnd
)
FROM Documents
Ho usato un CROSS JOIN di recente in un rapporto che usiamo per le vendite forcasting, il rapporto ha bisogno di uscire la quantità di vendite che una persona di vendita ha fatto in ogni conto di contabilità generale.
Quindi, nella relazione che faccio qualcosa di questo tenore:
SELECT gla.AccountN, s.SalespersonN
FROM
GLAccounts gla
CROSS JOIN Salesperson s
WHERE (gla.SalesAnalysis = 1 OR gla.AccountN = 47500)
Questo mi dà ogni account GL per ogni persona di vendite come:
SalesPsn AccountN 1000 40100 1000 40200 1000 40300 1000 48150 1000 49980 1000 49990 1005 40100 1005 40200 1005 40300 1054 48150 1054 49980 1054 49990 1078 40100 1078 40200 1078 40300 1078 48150 1078 49980 1078 49990 1081 40100 1081 40200 1081 40300 1081 48150 1081 49980 1081 49990 1188 40100 1188 40200 1188 40300 1188 48150 1188 49980 1188 49990
Per la creazione di grafici (report) in cui ogni raggruppamento deve avere un record anche se è pari a zero. (Ad esempio RadCharts)
ho avuto combinazioni di campo insolvenza del mattino dai miei dati di origine. Ci sono 5 tipi distinti, ma i dati sono combinazioni di 2 di questi. Così ho creato tabella di ricerca dei 5 valori distinti poi utilizzato un cross join per un'istruzione INSERT per compilare il resto. in questo modo
insert into LK_Insolvency (code,value)
select a.code+b.code, a.value+' '+b.value
from LK_Insolvency a
cross join LK_Insolvency b
where a.code <> b.code <--this makes sure the x product of the value with itself is not used as this does not appear in the source data.
Io personalmente cerco di evitare cartesiano di prodotti nelle mie query. Suppongo che ho un set di risultati di ogni combinazione della vostra unirsi potrebbe essere utile, ma di solito se io alla fine con uno, so di avere qualcosa che non va.