Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

स्लीक डायनेमिक ग्रुपबाय

यहां स्लिक 3.2.3 (और मेरे दृष्टिकोण पर कुछ पृष्ठभूमि) के लिए एक समाधान है:

आपने देखा होगा कि गतिशील रूप से चयन कॉलम तब तक आसान है जब तक आप एक निश्चित प्रकार मान सकते हैं, जैसे: columnNames = List("col1", "col2") tableQuery.map( r => columnNames.map(name => r.column[String](name)) )

लेकिन अगर आप इसी तरह का तरीका आजमाएं एक groupBy . के साथ ऑपरेशन, स्लिक शिकायत करेगा कि यह "does not know how to map the given types"

इसलिए, जबकि यह शायद ही एक सुरुचिपूर्ण समाधान है, आप कम से कम दोनों को स्थिर रूप से परिभाषित करके स्लिक की प्रकार-सुरक्षा को संतुष्ट कर सकते हैं:

  1. groupby स्तंभ प्रकार
  2. ऊपरी/निचली सीमा groupBy . की मात्रा पर है कॉलम

इन दो बाधाओं को लागू करने का एक आसान तरीका फिर से एक निश्चित प्रकार मान लेना और groupBy की सभी संभावित मात्राओं के लिए कोड को शाखा देना है। कॉलम।

आपको एक विचार देने के लिए यहां पूर्ण कार्यरत स्काला आरईपीएल सत्र है:

import java.io.File

import akka.actor.ActorSystem
import com.typesafe.config.ConfigFactory
import slick.jdbc.H2Profile.api._

import scala.concurrent.{Await, Future}
import scala.concurrent.duration._


val confPath = getClass.getResource("/application.conf")
val config = ConfigFactory.parseFile(new File(confPath.getPath)).resolve()
val db = Database.forConfig("slick.db", config)

implicit val system = ActorSystem("testSystem")
implicit val executionContext = system.dispatcher

case class AnyData(a: String, b: String)
case class GroupByFields(a: Option[String], b: Option[String])

class AnyTable(tag: Tag) extends Table[AnyData](tag, "macro"){
  def a = column[String]("a")
  def b = column[String]("b")
  def * = (a, b) <> ((AnyData.apply _).tupled, AnyData.unapply)
}

val table = TableQuery[AnyTable]

def groupByDynamically(groupBys: Seq[String]): DBIO[Seq[GroupByFields]] = {
  // ensures columns are returned in the right order
  def selectGroups(g: Map[String, Rep[Option[String]]]) = {
    (g.getOrElse("a", Rep.None[String]), g.getOrElse("b", Rep.None[String])).mapTo[GroupByFields]
  }

  val grouped = if (groupBys.lengthCompare(2) == 0) {
    table
      .groupBy( cols => (cols.column[String](groupBys(0)), cols.column[String](groupBys(1))) )
      .map{ case (groups, _) => selectGroups(Map(groupBys(0) -> Rep.Some(groups._1), groupBys(1) -> Rep.Some(groups._2))) }
  }
  else {
    // there should always be at least one group by specified
    table
      .groupBy(cols => cols.column[String](groupBys.head))
      .map{ case (groups, _) => selectGroups(Map(groupBys.head -> Rep.Some(groups))) }
  }

  grouped.result
}

val actions = for {
  _ <- table.schema.create
  _ <- table.map(a => (a.column[String]("a"), a.column[String]("b"))) += ("a1", "b1")
  _ <- table.map(a => (a.column[String]("a"), a.column[String]("b"))) += ("a2", "b2")
  _ <- table.map(a => (a.column[String]("a"), a.column[String]("b"))) += ("a2", "b3")
  queryResult <- groupByDynamically(Seq("b", "a"))
} yield queryResult

val result: Future[Seq[GroupByFields]] = db.run(actions.transactionally)
result.foreach(println)

Await.ready(result, Duration.Inf)

जहां यह बदसूरत हो जाता है, जब आप कुछ groupBy . से ऊपर हो सकते हैं कॉलम (अर्थात एक अलग if . होना 10+ मामलों के लिए शाखा नीरस हो जाएगी)। उम्मीद है कि कोई इस उत्तर में झपट्टा मारेगा और संपादित करेगा कि उस बॉयलरप्लेट को कुछ वाक्यात्मक चीनी या अमूर्त परत के पीछे कैसे छिपाया जाए।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL में कॉलम के प्रतिशत की गणना कैसे करें

  2. लारवेल परियोजना ERR_EMPTY_RESPONSE

  3. कुप्पी-SQLAlchemy - कई डेटाबेस के लिए फ्लाई कनेक्शन पर

  4. mysql अजगर कनेक्टर के साथ तैयार कथन करने का प्रयास करते समय मुझे NotImplementedError मिलता है

  5. पायथन ओडो एसक्यूएल अभिकथन त्रुटि:डेटाशैप रिकॉर्ड प्रकार होना चाहिए, 0 * {...} मिला