SELECT com UNION e com parâmetros ou não [RESOLVIDO]

Pessoal, tenho uma funcionalidade (que está ok) que recebe ou não parâmetro de uma lista… só que vou ter que aumentar esse SELECT, colocando um UNION, ou seja, agora terá que repetir as condições… só que não sei como gravar essas condições para apenas adicionar…

Consulta SQL fixa (ONDE EU QUERO E PRECISO ADICIONAR UM UNION):

	private static final String SQL_ATUAL = " SELECT (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Dispositivo.CodigoTecnologia) AS CodTecnologia, "
			+ "(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = SIMCard.CodigoOperadora) AS Operadora, "
			+ "(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Linha.CodigoStatusLinha) AS StatusLinha, "
			+ "COUNT(*) as Quantidade "
			+ "FROM SIMCard LEFT JOIN SIMCardDispositivo ON SIMCardDispositivo.SIMCard_Numero = SIMCard.Numero "
			+ "LEFT JOIN Dispositivo ON Dispositivo.Numero = SIMCardDispositivo.Dispositivo_Numero "
			+ "INNER JOIN Linha ON Linha.Numero = SIMCard.NumeroLinha "
			+ "LEFT JOIN Processamento ON (Processamento.Codigo = SIMCard.CodigoProcessamento OR Processamento.Codigo = Dispositivo.CodigoProcessamento) "
			+ "WHERE (";

segue minha classe:

StringBuilder sql = new StringBuilder("");

	public List<ConsultaGerarRelatorio> listaTecnologias(
			List<Integer> tecnologias, List<Integer> operadoras,
			List<Integer> status) {
		Connection conn = null;
		PreparedStatement ps = null;
		List<ConsultaGerarRelatorio> listaConsultaGeraRelatorio = new ArrayList<ConsultaGerarRelatorio>();

		if (!tecnologias.isEmpty()) {
			sql.append(" Dispositivo.CodigoTecnologia IN (");
			for (Iterator<Integer> it = tecnologias.iterator(); it.hasNext();) {
				it.next();
				sql.append("?");
				if (it.hasNext()) {
					sql.append(",");
				}
			}
			sql.append(")");
		}

		if (!operadoras.isEmpty()) {

			if (!tecnologias.isEmpty()) {
				sql.append(" AND SIMCard.CodigoOperadora IN (");
				for (Iterator<Integer> it = operadoras.iterator(); it.hasNext();) {
					it.next();
					sql.append("?");
					if (it.hasNext()) {
						sql.append(",");
					}
				}
				sql.append(")");

			} else {

				sql.append(" SIMCard.CodigoOperadora IN (");
				for (Iterator<Integer> it = operadoras.iterator(); it.hasNext();) {
					it.next();
					sql.append("?");
					if (it.hasNext()) {
						sql.append(",");
					}
				}
				sql.append(")");
			}
		}

		if (!status.isEmpty()) {

			if (!tecnologias.isEmpty() || !operadoras.isEmpty()) {
				sql.append(" AND Linha.CodigoStatusLinha IN (");
				for (Iterator<Integer> it = status.iterator(); it.hasNext();) {
					it.next();
					sql.append("?");
					if (it.hasNext()) {
						sql.append(",");
					}
				}
				sql.append(")");
			} else {

				sql.append(" Linha.CodigoStatusLinha IN (");
				for (Iterator<Integer> it = status.iterator(); it.hasNext();) {
					it.next();
					sql.append("?");
					if (it.hasNext()) {
						sql.append(",");
					}
				}
				sql.append(")");
			}
		}

		sql.append(" )");

		try {

			conn = ConnectionManager.obterConexao();
			ps = conn.prepareStatement(SQL_ATUAL + sql.toString() + GROUP);
			int indicePs = 1;

			if (!tecnologias.isEmpty()) {
				for (Integer i : tecnologias) {
					ps.setInt(indicePs++, i);
				}
			}
			if (!operadoras.isEmpty()) {
				for (Integer i : operadoras) {
					ps.setInt(indicePs++, i);
				}
			}
			if (!status.isEmpty()) {
				for (Integer i : status) {
					ps.setInt(indicePs++, i);
				}
			}

			System.out.println("Consulta: " + SQL_ATUAL + sql.toString()
					+ GROUP);

			ResultSet rs = ps.executeQuery();

			while (rs.next()) {

				ConsultaGerarRelatorio listaRelatorio = new ConsultaGerarRelatorio(
						rs.getString("CodTecnologia"),
						rs.getString("Operadora"), rs.getString("StatusLinha"),
						rs.getString("Quantidade"));

				listaConsultaGeraRelatorio.add(listaRelatorio);

				System.out.println(rs.getString("CodTecnologia") + " "
						+ rs.getString("Operadora") + " "
						+ rs.getString("StatusLinha") + " "
						+ rs.getString("Quantidade"));

			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			ConnectionManager.fecharConexao(conn, null, ps);
		}

		return listaConsultaGeraRelatorio;

	}

Cara não entendi sua dúvida …

O union deve ser usado com a mesma quantidade de colunas contido em outra query … por exemplo :

SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2

Senão houver esta condição não funcionará, portanto penso eu … você pode fazer assim …

faz a montagem desta query e junta(UNION) com a sua SQL_ATUAL… ou você já viu a possibilidade de mexer na sua SQL_ATUAL adicionando a necessidade do negócio , sem precisar incluir o UNION , por exemplo ?

É o seguinte…

Eu tenho esse SELECT que adicionei aqui… e nele vai virar um UNION, onde vou adicionar nova consulta…

A minha dúvida está em, como vou adicionar as condições iguais para ele… pois eu monto as condições de maneira dinâmica, assim, não sei como adicionar as condições.

O select ficaria assim:

[code]
– Consulta coletiva exeplo dos campos para juntar com a consulta unitária histórico
SELECT DISTINCT (Dispositivo.Numero) AS Dispositivo,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Dispositivo.CodigoTecnologia) AS CodTecnologia,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Dispositivo.CodigoAPNConfigurada) AS APNConfigurada,
(SIMCard.Numero) AS SIMCard,
(Linha.Numero) AS Linha,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = SIMCard.CodigoOperadora) AS Operadora,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = SIMCard.CodigoAPNProvisionada) AS APNProvisionada,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = SIMCard.CodigoStatusSIMCard) AS StatusSIMCard,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Processamento.CodigoFonteDados) AS Fonte,
(Processamento.dataProcessamento) AS DtAlteracao,
(Dispositivo.IMEI) AS IMEI,
(SIMCard.IMSI) AS IMSI,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Linha.CodigoStatusLinha) AS StatusLinha,
(SIMCard.ConsumoDados) AS ConsDados,
(SIMCard.MatriculaAlteracao) AS Matricula
FROM Dispositivo LEFT JOIN SimcardDispositivo ON SimcardDispositivo.Dispositivo_numero = Dispositivo.Numero
LEFT JOIN SIMCard ON SIMCard.Numero = SIMCardDispositivo.SIMCard_Numero
LEFT JOIN Linha ON Linha.Numero = SIMCard.NumeroLinha
LEFT JOIN Processamento ON (Processamento.Codigo = SIMCard.CodigoProcessamento OR Processamento.Codigo = Dispositivo.CodigoProcessamento)
WHERE Dispositivo.Numero = ‘aaaaaa’

UNION ALL
– Unitária
SELECT DISTINCT (Historico.NumeroDispositivo) AS Dispositivo,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoTecnologia) AS CodTecnologia,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoAPNConfigurada) AS APNConfigurada,
(Historico.NumeroSIMCard) AS SIMCard,
(Historico.NumeroLinha) AS Linha,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoOperadora) AS Operadora,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoAPNProvisionada) AS APNProvisionada,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.StatusSIMCard) AS StatusSIMCard,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Processamento.CodigoFonteDados) AS Fonte,
(Processamento.dataProcessamento) AS DtAlteracao,
(Historico.IMEI) AS IMEI,
(Historico.IMSI) AS IMSI,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.StatusLinha) AS StatusLinha,
(Historico.ConsumoDados) AS ConsDados,
(Processamento.MatriculaCadastro) AS Matricula
FROM Historico, Processamento
WHERE Historico.CodigoProcessamento = Processamento.Codigo
AND Historico.NumeroDispositivo = ‘aaaaaa’[/code]

as condições where serão as mesmas… mas na hora que eu to montando, com o índice em cada um, não sei continuar, para preecher igual ao primeiro… fui mais claro? ou ainda ta confuso?

Consegui ajuntar colocando os parâmetros… bastou eu repetir o processo de preenchimento… sei que talvez não seja a melhor maneira mais funciona

só que to apanhando para agurpar… fica dando erro:

[code]Consulta: SELECT (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoTecnologia) AS CodTecnologia, (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoOperadora) AS Operadora, (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.StatusLinha) AS StatusLinha, COUNT() as Quantidade FROM Historico WHERE ( Historico.CodigoOperadora IN (?) AND Historico.StatusLinha IN (?) ) UNION ALL SELECT (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Dispositivo.CodigoTecnologia) AS CodTecnologia, (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = SIMCard.CodigoOperadora) AS Operadora, (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Linha.CodigoStatusLinha) AS StatusLinha, COUNT() as Quantidade FROM SIMCard LEFT JOIN SIMCardDispositivo ON SIMCardDispositivo.SIMCard_Numero = SIMCard.Numero LEFT JOIN Dispositivo ON Dispositivo.Numero = SIMCardDispositivo.Dispositivo_Numero INNER JOIN Linha ON Linha.Numero = SIMCard.NumeroLinha LEFT JOIN Processamento ON (Processamento.Codigo = SIMCard.CodigoProcessamento OR Processamento.Codigo = Dispositivo.CodigoProcessamento) WHERE ( SIMCard.CodigoOperadora IN (?) AND Linha.CodigoStatusLinha IN (?) ) GROUP BY CodTecnologia, Operadora, StatusLinha ORDER BY CodTecnologia, Operadora, StatusLinha
org.postgresql.util.PSQLException: ERRO: subconsulta utiliza coluna desagrupada “historico.codigotecnologia” na consulta externa
Posição: 66

[/code]

Neste caso do erro, o ideal é você pegar a query que esta sendo gerada no java e rodar no banco diretamente , me parece que uma coluna não esta sendo agrupada , faça isto e veja o que retorna …

Aleksandro blz?

Da o mesmo erro…

ERRO: subconsulta utiliza coluna desagrupada “historico.codigotecnologia” na consulta externa
SQL state: 42803
Character: 65

[quote=Pacato]Aleksandro blz?

Da o mesmo erro…

ERRO: subconsulta utiliza coluna desagrupada “historico.codigotecnologia” na consulta externa
SQL state: 42803
Character: 65[/quote]

Mande a query que você executou no BD …? para eu dar uma olhada …

Segue consulta:

[code]SELECT (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoTecnologia) AS CodTecnologia,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoOperadora) AS Operadora,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.StatusLinha) AS StatusLinha,
COUNT(*) as Quantidade
FROM Historico
WHERE ( Historico.StatusLinha IN (16) )
UNION ALL

SELECT (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Dispositivo.CodigoTecnologia) AS CodTecnologia,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = SIMCard.CodigoOperadora) AS Operadora,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Linha.CodigoStatusLinha) AS StatusLinha,
COUNT(*) as Quantidade
FROM SIMCard LEFT JOIN SIMCardDispositivo ON SIMCardDispositivo.SIMCard_Numero = SIMCard.Numero LEFT JOIN Dispositivo ON Dispositivo.Numero = SIMCardDispositivo.Dispositivo_Numero INNER JOIN Linha ON Linha.Numero = SIMCard.NumeroLinha LEFT JOIN Processamento ON (Processamento.Codigo = SIMCard.CodigoProcessamento OR Processamento.Codigo = Dispositivo.CodigoProcessamento)
WHERE ( Linha.CodigoStatusLinha IN (16) )

GROUP BY CodTecnologia, Operadora, StatusLinha ORDER BY CodTecnologia, Operadora, StatusLinha [/code]

valeu

tenta assim :

select CodTecnologia, Operadora, StatusLinha FROM (

SELECT
  (SELECT Dominio.Nome
  FROM Dominio
  WHERE Dominio.Codigo = Historico.CodigoTecnologia
  ) AS CodTecnologia,
  (SELECT Dominio.Nome
  FROM Dominio
  WHERE Dominio.Codigo = Historico.CodigoOperadora
  ) AS Operadora,
  (SELECT Dominio.Nome
  FROM Dominio
  WHERE Dominio.Codigo = Historico.StatusLinha
  )        AS StatusLinha,
  COUNT(*) AS Quantidade
FROM Historico
WHERE ( Historico.StatusLinha IN (16) )
UNION ALL
SELECT
  (SELECT Dominio.Nome
  FROM Dominio
  WHERE Dominio.Codigo = Dispositivo.CodigoTecnologia
  ) AS CodTecnologia,
  (SELECT Dominio.Nome
  FROM Dominio
  WHERE Dominio.Codigo = SIMCard.CodigoOperadora
  ) AS Operadora,
  (SELECT Dominio.Nome
  FROM Dominio
  WHERE Dominio.Codigo = Linha.CodigoStatusLinha
  )        AS StatusLinha,
  COUNT(*) AS Quantidade
FROM SIMCard
LEFT JOIN SIMCardDispositivo
ON SIMCardDispositivo.SIMCard_Numero = SIMCard.Numero
LEFT JOIN Dispositivo
ON Dispositivo.Numero = SIMCardDispositivo.Dispositivo_Numero
INNER JOIN Linha
ON Linha.Numero = SIMCard.NumeroLinha
LEFT JOIN Processamento
ON (Processamento.Codigo         = SIMCard.CodigoProcessamento
OR PROCESSAMENTO.CODIGO          = DISPOSITIVO.CODIGOPROCESSAMENTO)
WHERE ( Linha.CodigoStatusLinha IN (16) ))
GROUP BY CodTecnologia,
  Operadora,
  StatusLinha
ORDER BY CodTecnologia,
  Operadora,
  StatusLinha 

Seu agrupamento(group by) não pode ficar para fora …

Da erro

ERRO: subconsulta no FROM deve ter um aliás
SQL state: 42601
Hint: Por exemplo, FROM (SELECT …) [AS] foo.
Character: 51

coloque um alias …

assim por exemplo :

o a será alias de toda consulta interna …

Assim vai complicar aleksandro… pois eu to montando o select… e nem imagino como colocaria em cima mais uma condição… to tentando ver um outro jeito…

mas valeu mesmo pela força

[quote=Pacato]Assim vai complicar aleksandro… pois eu to montando o select… e nem imagino como colocaria em cima mais uma condição… to tentando ver um outro jeito…

mas valeu mesmo pela força[/quote]

Cara mas você rodou no BD funcionou ? este é o primeiro passo … depois você faz as respectivas modificações no java …entendeu …

Não funcionou… por isso falei

Funcionou assim:

SELECT (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoTecnologia) AS CodTecnologia,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoOperadora) AS Operadora,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.StatusLinha) AS StatusLinha,
COUNT(*) as Quantidade
FROM Historico
WHERE ( Historico.StatusLinha IN (16) )
GROUP BY CodTecnologia, Operadora, StatusLinha

UNION ALL

SELECT (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Dispositivo.CodigoTecnologia) AS CodTecnologia,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = SIMCard.CodigoOperadora) AS Operadora,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Linha.CodigoStatusLinha) AS StatusLinha,
COUNT(*) as Quantidade
FROM SIMCard LEFT JOIN SIMCardDispositivo ON SIMCardDispositivo.SIMCard_Numero = SIMCard.Numero LEFT JOIN Dispositivo ON Dispositivo.Numero = SIMCardDispositivo.Dispositivo_Numero INNER JOIN Linha ON Linha.Numero = SIMCard.NumeroLinha LEFT JOIN Processamento ON (Processamento.Codigo = SIMCard.CodigoProcessamento OR Processamento.Codigo = Dispositivo.CodigoProcessamento)
WHERE ( Linha.CodigoStatusLinha IN (16) )

GROUP BY CodTecnologia, Operadora, StatusLinha ORDER BY CodTecnologia, Operadora, StatusLinha

Só que os resultados estão repetidos… queria colocar na mesma linha…

por exemplo

veio
A - A - A
A - A - A

ao invés de AA - AA - AA

entende??

[quote=Pacato]Não funcionou… por isso falei

Funcionou assim:

SELECT (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoTecnologia) AS CodTecnologia,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoOperadora) AS Operadora,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.StatusLinha) AS StatusLinha,
COUNT(*) as Quantidade
FROM Historico
WHERE ( Historico.StatusLinha IN (16) )
GROUP BY CodTecnologia, Operadora, StatusLinha

UNION ALL

SELECT (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Dispositivo.CodigoTecnologia) AS CodTecnologia,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = SIMCard.CodigoOperadora) AS Operadora,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Linha.CodigoStatusLinha) AS StatusLinha,
COUNT(*) as Quantidade
FROM SIMCard LEFT JOIN SIMCardDispositivo ON SIMCardDispositivo.SIMCard_Numero = SIMCard.Numero LEFT JOIN Dispositivo ON Dispositivo.Numero = SIMCardDispositivo.Dispositivo_Numero INNER JOIN Linha ON Linha.Numero = SIMCard.NumeroLinha LEFT JOIN Processamento ON (Processamento.Codigo = SIMCard.CodigoProcessamento OR Processamento.Codigo = Dispositivo.CodigoProcessamento)
WHERE ( Linha.CodigoStatusLinha IN (16) )

GROUP BY CodTecnologia, Operadora, StatusLinha ORDER BY CodTecnologia, Operadora, StatusLinha

Só que os resultados estão repetidos… queria colocar na mesma linha…

por exemplo

veio
A - A - A
A - A - A

ao invés de AA - AA - AA

entende??[/quote]

Então você não quer unir seu select e sim concatenar colunas … seu BD é postgres certo ? faça assim então :

Consegui assim…

select CodTecnologia, Operadora, StatusLinha , sum(Quantidade)
from
(
SELECT (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoTecnologia) AS CodTecnologia,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.CodigoOperadora) AS Operadora,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Historico.StatusLinha) AS StatusLinha,
COUNT(*) as Quantidade
FROM Historico
WHERE ( Historico.StatusLinha IN (16) )
GROUP BY CodTecnologia, Operadora, StatusLinha

UNION ALL

SELECT (SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Dispositivo.CodigoTecnologia) AS CodTecnologia,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = SIMCard.CodigoOperadora) AS Operadora,
(SELECT Dominio.Nome FROM Dominio WHERE Dominio.Codigo = Linha.CodigoStatusLinha) AS StatusLinha,
COUNT(*) as Quantidade
FROM SIMCard LEFT JOIN SIMCardDispositivo ON SIMCardDispositivo.SIMCard_Numero = SIMCard.Numero LEFT JOIN Dispositivo ON Dispositivo.Numero = SIMCardDispositivo.Dispositivo_Numero INNER JOIN Linha ON Linha.Numero = SIMCard.NumeroLinha LEFT JOIN Processamento ON (Processamento.Codigo = SIMCard.CodigoProcessamento OR Processamento.Codigo = Dispositivo.CodigoProcessamento)
WHERE ( Linha.CodigoStatusLinha IN (16) )
GROUP BY CodTecnologia, Operadora, StatusLinha
) tabela_virtual
group by CodTecnologia, Operadora, StatusLinha
ORDER BY CodTecnologia, Operadora, StatusLinha

valeu…

abs

legal.